Refactor FollowersList to use UserPreview and LoadMore

This commit is contained in:
srgooglo 2025-07-04 14:09:58 +02:00
parent 678c0c1a4c
commit a608f967c0
2 changed files with 96 additions and 118 deletions

View File

@ -1,101 +1,98 @@
import React from "react"
import * as antd from "antd"
import { Icons } from "@components/Icons"
import LoadMore from "@components/LoadMore"
import UserPreview from "@components/UserPreview"
import FollowsModel from "@models/follows"
import "./index.less"
const FollowerItem = ({
follower,
onClick,
index
}) => {
return <div
className="follower"
onClick={onClick}
key={index}
>
<div className="avatar">
<antd.Avatar shape="square" src={follower.avatar} />
</div>
<div className="names">
<div>
<h2>
{follower.fullName ?? follower.username}
</h2>
</div>
<div>
<span>
@{follower.username}
</span>
</div>
</div>
</div>
const FollowerItem = React.memo(({ data }) => {
return <UserPreview user={data} />
})
FollowerItem.displayName = "FollowerItem"
const FollowersList = (props) => {
const [loading, setLoading] = React.useState(false)
const [followers, setFollowers] = React.useState(props.followers ?? [])
const [hasMore, setHasMore] = React.useState(true)
const page = React.useRef(0)
const userId = React.useRef(props.user_id)
const loadFollowers = React.useCallback(async () => {
setLoading(true)
console.log(
`Loading Followers for [${userId.current}] page [${page.current}]`,
)
const followers = await FollowsModel.getFollowers(userId.current, {
fetchData: true,
limit: 10,
page: page.current,
}).catch((err) => {
console.error(err)
app.message.error("Failed to fetch followers")
return null
})
setLoading(false)
if (followers) {
console.log(`Loaded Followers :`, followers)
setFollowers((prev) => {
return [...prev, ...followers.items]
})
if (followers.has_more) {
setHasMore(true)
} else {
setHasMore(false)
}
}
}, [userId.current])
const onLoadMore = React.useCallback(() => {
page.current += 1
loadFollowers()
}, [userId.current])
React.useEffect(() => {
if (!props.followers) {
if (props.user_id) {
userId.current = props.user_id
page.current = 0
setFollowers([])
setHasMore(true)
loadFollowers()
}
}
}, [props.user_id])
if (!loading && followers.length === 0) {
return (
<antd.Result icon={<Icons.FiUserX style={{ fontSize: "50px" }} />}>
<h2>It's seems this user has no followers, yet.</h2>
<h3>Maybe you can help them out?</h3>
</antd.Result>
)
}
return (
<LoadMore
className="followersList"
onBottom={onLoadMore}
hasMore={hasMore}
>
{followers.map((data) => {
return <FollowerItem key={data._id} data={data} />
})}
</LoadMore>
)
}
export default (props) => {
const [loading, setLoading] = React.useState(false)
const [followers, setFollowers] = React.useState(props.followers ?? [])
const goToProfile = (username) => {
app.navigation.goToAccount(username)
}
const loadFollowers = async () => {
setLoading(true)
console.log(`Loading Followers for [${props.user_id}]...`)
const followers = await FollowsModel.getFollowers(props.user_id, true).catch((err) => {
console.error(err)
app.message.error("Failed to fetch followers")
return null
})
setLoading(false)
if (followers) {
console.log(`Loaded Followers: [${followers.length}] >`, followers)
setFollowers(followers)
}
}
React.useEffect(() => {
if (!props.followers) {
if (props.user_id) {
loadFollowers()
}
}
}, [])
if (loading) {
return <antd.Skeleton active />
}
if (followers.length === 0) {
return <antd.Result
icon={<Icons.FiUserX style={{ fontSize: "50px" }} />}
>
<h2>
It's seems this user has no followers, yet.
</h2>
<h3>
Maybe you can help them out?
</h3>
</antd.Result>
}
return <div className="followersList">
{
followers.map((follower, index) => {
return <FollowerItem
index={index}
follower={follower}
onClick={() => goToProfile(follower.username)}
/>
})
}
</div>
}
export default FollowersList

View File

@ -33,37 +33,18 @@
}
.followersList {
.follower {
display: inline-flex;
align-items: center;
display: flex;
flex-direction: column;
width: 100%;
gap: 10px;
margin-bottom: 10px;
padding: 10px;
.userPreview {
background-color: var(--background-color-primary);
border-radius: 8px;
border: 1px solid var(--border-color);
cursor: pointer;
padding: 5px 10px;
h2 {
margin: 0;
font-size: 22px;
line-height: 26px;
}
>div {
margin-right: 10px;
}
.names {
display: flex;
flex-direction: column;
}
width: 100%;
}
.follower:last-child {
margin-bottom: 0;
}
}
}