104 lines
2.9 KiB
JavaScript
104 lines
2.9 KiB
JavaScript
import { useCallback, useEffect, useState } from 'react'
|
|
import { usersRef } from '../../../config/firebase'
|
|
import { ensureAuthenticated } from '../../../utils/authRedirect'
|
|
|
|
const usePlaybackOwner = ({
|
|
item,
|
|
userCache,
|
|
getUserByUid,
|
|
currentUID,
|
|
followUser,
|
|
unfollowUser,
|
|
}) => {
|
|
const [owner, setOwner] = useState(
|
|
item?.userId && userCache?.current?.get(item.userId) ? userCache.current.get(item.userId) : null
|
|
)
|
|
|
|
useEffect(() => {
|
|
let cancelled = false
|
|
const run = async () => {
|
|
try {
|
|
const uid = item?.userId
|
|
if (!uid || !userCache) return
|
|
const cached = userCache.current.get(uid)
|
|
if (cached) {
|
|
if (!cancelled) setOwner(cached)
|
|
return
|
|
}
|
|
const user = await getUserByUid?.(uid)
|
|
if (!cancelled && user) {
|
|
userCache.current.set(uid, user)
|
|
setOwner(user)
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
run()
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
}, [item?.userId, userCache, getUserByUid])
|
|
|
|
useEffect(() => {
|
|
const uid = item?.userId
|
|
if (!uid) return
|
|
const unsub = usersRef.doc(uid).onSnapshot(
|
|
(doc) => {
|
|
if (doc?.exists) {
|
|
const data = { id: doc.id, ...doc.data() }
|
|
setOwner(data)
|
|
try {
|
|
userCache?.current?.set(uid, data)
|
|
} catch (e) {}
|
|
}
|
|
},
|
|
() => {}
|
|
)
|
|
return () => unsub?.()
|
|
}, [item?.userId, userCache])
|
|
|
|
const [isFollowing, setIsFollowing] = useState(false)
|
|
const [isFollowActionPending, setIsFollowActionPending] = useState(false)
|
|
useEffect(() => {
|
|
const list = Array.isArray(owner?.followedBy) ? owner.followedBy : []
|
|
setIsFollowing(currentUID ? list.includes(currentUID) : false)
|
|
}, [owner?.followedBy, currentUID])
|
|
|
|
const toggleFollow = useCallback(async () => {
|
|
if (!owner?.id || owner.id === currentUID) return
|
|
if (isFollowActionPending) return
|
|
if (
|
|
!ensureAuthenticated(currentUID, {
|
|
onIntercept: () => {
|
|
setIsFollowActionPending(false)
|
|
},
|
|
})
|
|
) {
|
|
return
|
|
}
|
|
try {
|
|
setIsFollowActionPending(true)
|
|
const next = !isFollowing
|
|
setIsFollowing(next)
|
|
setOwner((prev) => {
|
|
const fb = Array.isArray(prev?.followedBy) ? prev.followedBy : []
|
|
const newFb = next
|
|
? Array.from(new Set([...fb, currentUID]))
|
|
: fb.filter((x) => x !== currentUID)
|
|
return prev ? { ...prev, followedBy: newFb } : prev
|
|
})
|
|
if (next) await followUser?.(owner.id)
|
|
else await unfollowUser?.(owner.id)
|
|
global.setTimeout(() => {
|
|
setIsFollowActionPending(false)
|
|
}, 1000)
|
|
} catch (e) {
|
|
setIsFollowing((v) => !v)
|
|
setIsFollowActionPending(false)
|
|
}
|
|
}, [currentUID, followUser, isFollowActionPending, isFollowing, owner?.id, unfollowUser])
|
|
|
|
return { owner, isFollowing, isFollowActionPending, toggleFollow }
|
|
}
|
|
|
|
export default usePlaybackOwner
|