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

View File

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