feat: fixes and formatter
This commit is contained in:
@@ -1,147 +1,131 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { View, StyleSheet } from "react-native";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useUser } from "../../../providers/UserDataProvider";
|
||||
import { Routes } from "../../../navigation";
|
||||
import { navigate } from "../../../navigation/NavigationService";
|
||||
import { openComments } from "../../../components/bottomsheets/CommentsBottomSheet";
|
||||
import {
|
||||
createPlaybackSharePayload,
|
||||
openShareSheet,
|
||||
} from "../../../utils/shareSheet";
|
||||
import {
|
||||
getProjectLikes,
|
||||
LIKE_TARGET,
|
||||
toggleProjectLike,
|
||||
} from "../../../utils/likes";
|
||||
import { ensureAuthenticated } from "../../../utils/authRedirect";
|
||||
import PlaybackVideo from "./PlaybackVideo";
|
||||
import PlaybackActions from "./PlaybackActions";
|
||||
import PlaybackLyricsCard from "./PlaybackLyricsCard";
|
||||
import usePlaybackOwner from "./usePlaybackOwner";
|
||||
import usePlaybackPlayer from "./usePlaybackPlayer";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { View, StyleSheet } from 'react-native'
|
||||
import { responsiveHeight } from 'react-native-responsive-dimensions'
|
||||
import { SheetManager } from 'react-native-actions-sheet'
|
||||
import { useUser } from '../../../providers/UserDataProvider'
|
||||
import { Routes } from '../../../navigation'
|
||||
import { navigate } from '../../../navigation/NavigationService'
|
||||
import { openComments } from '../../../components/bottomsheets/CommentsBottomSheet'
|
||||
import { createPlaybackSharePayload, openShareSheet } from '../../../utils/shareSheet'
|
||||
import { getProjectLikes, LIKE_TARGET, toggleProjectLike } from '../../../utils/likes'
|
||||
import { ensureAuthenticated } from '../../../utils/authRedirect'
|
||||
import PlaybackVideo from './PlaybackVideo'
|
||||
import PlaybackActions from './PlaybackActions'
|
||||
import PlaybackLyricsCard from './PlaybackLyricsCard'
|
||||
import usePlaybackOwner from './usePlaybackOwner'
|
||||
import usePlaybackPlayer from './usePlaybackPlayer'
|
||||
|
||||
const PlaybackItem = ({ item, isActive, userCache }) => {
|
||||
const { currentUID, followUser, unfollowUser, getUserByUid } = useUser() || {};
|
||||
const { owner, isFollowing, isFollowActionPending, toggleFollow } =
|
||||
usePlaybackOwner({
|
||||
item,
|
||||
userCache,
|
||||
getUserByUid,
|
||||
currentUID,
|
||||
followUser,
|
||||
unfollowUser,
|
||||
});
|
||||
const { currentUID, followUser, unfollowUser, getUserByUid } = useUser() || {}
|
||||
const { owner, isFollowing, isFollowActionPending, toggleFollow } = usePlaybackOwner({
|
||||
item,
|
||||
userCache,
|
||||
getUserByUid,
|
||||
currentUID,
|
||||
followUser,
|
||||
unfollowUser,
|
||||
})
|
||||
|
||||
const initialLikedBy = getProjectLikes(item, LIKE_TARGET.PLAYBACK);
|
||||
const [isLiked, setIsLiked] = useState(
|
||||
currentUID ? initialLikedBy.includes(currentUID) : false
|
||||
);
|
||||
const [likesCount, setLikesCount] = useState(initialLikedBy.length);
|
||||
const initialLikedBy = getProjectLikes(item, LIKE_TARGET.PLAYBACK)
|
||||
const [isLiked, setIsLiked] = useState(currentUID ? initialLikedBy.includes(currentUID) : false)
|
||||
const [likesCount, setLikesCount] = useState(initialLikedBy.length)
|
||||
|
||||
useEffect(() => {
|
||||
const lb = getProjectLikes(item, LIKE_TARGET.PLAYBACK);
|
||||
setLikesCount(lb.length);
|
||||
setIsLiked(currentUID ? lb.includes(currentUID) : false);
|
||||
}, [item?.likes?.playback, currentUID]);
|
||||
const lb = getProjectLikes(item, LIKE_TARGET.PLAYBACK)
|
||||
setLikesCount(lb.length)
|
||||
setIsLiked(currentUID ? lb.includes(currentUID) : false)
|
||||
}, [item?.likes?.playback, currentUID])
|
||||
|
||||
const commentsCount = useMemo(
|
||||
() => Number(item?.commentsCount || 0),
|
||||
[item?.commentsCount]
|
||||
);
|
||||
const commentsCount = useMemo(() => Number(item?.commentsCount || 0), [item?.commentsCount])
|
||||
|
||||
const projectTitle = typeof item?.title === "string" ? item.title.trim() : "";
|
||||
const projectTitle = typeof item?.title === 'string' ? item.title.trim() : ''
|
||||
|
||||
const creatorName = useMemo(() => {
|
||||
if (owner?.displayName) return owner.displayName;
|
||||
if (owner?.artistName) return owner.artistName;
|
||||
if (owner?.userName) return owner.userName;
|
||||
if (typeof item?.userName === "string") return item.userName;
|
||||
return "";
|
||||
}, [item?.userName, owner?.artistName, owner?.displayName, owner?.userName]);
|
||||
if (owner?.displayName) return owner.displayName
|
||||
if (owner?.artistName) return owner.artistName
|
||||
if (owner?.userName) return owner.userName
|
||||
if (typeof item?.userName === 'string') return item.userName
|
||||
return ''
|
||||
}, [item?.userName, owner?.artistName, owner?.displayName, owner?.userName])
|
||||
|
||||
const { videoUrl, videoPlayer, currentTimeS } = usePlaybackPlayer({
|
||||
item,
|
||||
isActive,
|
||||
});
|
||||
})
|
||||
|
||||
const alignedWords = useMemo(() => {
|
||||
const idx = Number(item?.songIndex) || 0;
|
||||
const ts = item?.musicTimestamps?.[idx];
|
||||
const arr = Array.isArray(ts?.alignedWords) ? ts.alignedWords : [];
|
||||
const idx = Number(item?.songIndex) || 0
|
||||
const ts = item?.musicTimestamps?.[idx]
|
||||
const arr = Array.isArray(ts?.alignedWords) ? ts.alignedWords : []
|
||||
return arr.map((w) => ({
|
||||
word: String(w?.word ?? ""),
|
||||
word: String(w?.word ?? ''),
|
||||
startS: Number(w?.startS ?? 0),
|
||||
endS: Number(w?.endS ?? 0),
|
||||
}));
|
||||
}, [item?.musicTimestamps, item?.songIndex]);
|
||||
}))
|
||||
}, [item?.musicTimestamps, item?.songIndex])
|
||||
|
||||
const sharePayload = useMemo(() => {
|
||||
if (!item?.id) return null;
|
||||
if (!item?.id) return null
|
||||
return createPlaybackSharePayload({
|
||||
projectId: item.id,
|
||||
title: projectTitle || undefined,
|
||||
artist: creatorName || undefined,
|
||||
playbackUrl: videoUrl || undefined,
|
||||
});
|
||||
}, [creatorName, item?.id, projectTitle, videoUrl]);
|
||||
})
|
||||
}, [creatorName, item?.id, projectTitle, videoUrl])
|
||||
|
||||
const handleShare = useCallback(() => {
|
||||
if (sharePayload) {
|
||||
openShareSheet(sharePayload);
|
||||
openShareSheet(sharePayload)
|
||||
}
|
||||
}, [sharePayload]);
|
||||
}, [sharePayload])
|
||||
|
||||
const handleReport = useCallback(() => {
|
||||
if (!item?.id) return;
|
||||
SheetManager.show("Report", {
|
||||
if (!item?.id) return
|
||||
SheetManager.show('Report', {
|
||||
payload: {
|
||||
targetType: "playback",
|
||||
targetType: 'playback',
|
||||
projectId: item?.id || null,
|
||||
playbackId: item?.id || null,
|
||||
title: item?.title || "",
|
||||
title: item?.title || '',
|
||||
ownerId: item?.userId || null,
|
||||
},
|
||||
});
|
||||
}, [item?.id, item?.title, item?.userId]);
|
||||
})
|
||||
}, [item?.id, item?.title, item?.userId])
|
||||
|
||||
const handleLike = useCallback(async () => {
|
||||
try {
|
||||
if (!item?.id) return;
|
||||
if (!item?.id) return
|
||||
if (!ensureAuthenticated(currentUID)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
const nextLiked = !isLiked;
|
||||
setIsLiked(nextLiked);
|
||||
setLikesCount((c) => Math.max(0, c + (nextLiked ? 1 : -1)));
|
||||
const nextLiked = !isLiked
|
||||
setIsLiked(nextLiked)
|
||||
setLikesCount((c) => Math.max(0, c + (nextLiked ? 1 : -1)))
|
||||
|
||||
await toggleProjectLike({
|
||||
projectId: item.id,
|
||||
currentUID,
|
||||
target: LIKE_TARGET.PLAYBACK,
|
||||
next: nextLiked,
|
||||
});
|
||||
})
|
||||
} catch (e) {
|
||||
setIsLiked((v) => !v);
|
||||
setLikesCount((c) => (isLiked ? c + 1 : Math.max(0, c - 1)));
|
||||
setIsLiked((v) => !v)
|
||||
setLikesCount((c) => (isLiked ? c + 1 : Math.max(0, c - 1)))
|
||||
}
|
||||
}, [currentUID, isLiked, item?.id]);
|
||||
}, [currentUID, isLiked, item?.id])
|
||||
|
||||
const handleCommentPress = useCallback(() => {
|
||||
if (item?.id) openComments(item.id);
|
||||
}, [item?.id]);
|
||||
if (item?.id) openComments(item.id)
|
||||
}, [item?.id])
|
||||
|
||||
const onOpenProfile = useCallback(() => {
|
||||
navigate(Routes.SingerProfile, { userId: item?.userId });
|
||||
}, [item?.userId]);
|
||||
navigate(Routes.SingerProfile, { userId: item?.userId })
|
||||
}, [item?.userId])
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<PlaybackVideo
|
||||
videoUrl={videoUrl}
|
||||
videoPlayer={videoPlayer}
|
||||
/>
|
||||
<PlaybackVideo videoUrl={videoUrl} videoPlayer={videoPlayer} />
|
||||
<View style={styles.overlay}>
|
||||
<PlaybackActions
|
||||
owner={owner}
|
||||
@@ -165,21 +149,21 @@ const PlaybackItem = ({ item, isActive, userCache }) => {
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
height: responsiveHeight(100),
|
||||
position: "relative",
|
||||
backgroundColor: "black",
|
||||
position: 'relative',
|
||||
backgroundColor: 'black',
|
||||
},
|
||||
overlay: {
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
bottom: 130,
|
||||
gap: 18,
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
export default PlaybackItem;
|
||||
export default PlaybackItem
|
||||
|
||||
Reference in New Issue
Block a user