display track duration

This commit is contained in:
SrGooglo 2025-06-16 20:42:29 +00:00
parent 9ad8b33057
commit 22c6279798
2 changed files with 96 additions and 19 deletions

View File

@ -14,6 +14,14 @@ import { Context as PlaylistContext } from "@contexts/WithPlaylistContext"
import "./index.less" import "./index.less"
function secondsToIsoTime(seconds) {
const minutes = Math.floor(seconds / 60)
return `${minutes}:${Math.floor(seconds % 60)
.toString()
.padStart(2, "0")}`
}
const handlers = { const handlers = {
like: async (ctx, track) => { like: async (ctx, track) => {
await MusicModel.toggleItemFavourite("track", track._id, true) await MusicModel.toggleItemFavourite("track", track._id, true)
@ -51,7 +59,7 @@ const Track = (props) => {
const isCurrent = track_manifest?._id === props.track._id const isCurrent = track_manifest?._id === props.track._id
const isPlaying = isCurrent && playback_status === "playing" const isPlaying = isCurrent && playback_status === "playing"
const handleClickPlayBtn = React.useCallback(() => { const handleClickPlayBtn = () => {
if (typeof props.onPlay === "function") { if (typeof props.onPlay === "function") {
return props.onPlay(props.track) return props.onPlay(props.track)
} }
@ -65,7 +73,7 @@ const Track = (props) => {
} else { } else {
app.cores.player.playback.toggle() app.cores.player.playback.toggle()
} }
}) }
const handleOnClickItem = React.useCallback(() => { const handleOnClickItem = React.useCallback(() => {
if (props.onClick) { if (props.onClick) {
@ -75,9 +83,9 @@ const Track = (props) => {
if (app.isMobile) { if (app.isMobile) {
handleClickPlayBtn() handleClickPlayBtn()
} }
}) }, [])
const handleMoreMenuOpen = () => { const handleMoreMenuOpen = React.useCallback(() => {
if (app.isMobile) { if (app.isMobile) {
return return
} }
@ -85,9 +93,9 @@ const Track = (props) => {
return setMoreMenuOpened((prev) => { return setMoreMenuOpened((prev) => {
return !prev return !prev
}) })
} }, [])
const handleMoreMenuItemClick = (e) => { const handleMoreMenuItemClick = React.useCallback((e) => {
const { key } = e const { key } = e
if (typeof handlers[key] === "function") { if (typeof handlers[key] === "function") {
@ -101,7 +109,7 @@ const Track = (props) => {
props.track, props.track,
) )
} }
} }, [])
const moreMenuItems = React.useMemo(() => { const moreMenuItems = React.useMemo(() => {
const items = [ const items = [
@ -162,6 +170,9 @@ const Track = (props) => {
return items return items
}, [props.track]) }, [props.track])
const trackDuration =
props.track?.metadata?.duration ?? props.track?.duration
return ( return (
<div <div
id={props.track._id} id={props.track._id}
@ -201,6 +212,14 @@ const Track = (props) => {
} }
onClick={handleClickPlayBtn} onClick={handleClickPlayBtn}
/> />
{/* {props.track?.metadata?.duration && (
<div className="music-track_play_duration">
{secondsToIsoTime(
props.track.metadata.duration,
)}
</div>
)} */}
</div> </div>
)} )}
@ -214,13 +233,19 @@ const Track = (props) => {
className="music-track_details" className="music-track_details"
onClick={handleOnClickItem} onClick={handleOnClickItem}
> >
<div className="music-track_title"> <div className="music-track_titles">
<span> <span className="music-track_title">
{props.track.service === "tidal" && ( {props.track.service === "tidal" && (
<Icons.SiTidal /> <Icons.SiTidal />
)} )}
{props.track.title} {props.track.title}
</span> </span>
{props.track.version && (
<span className="music-track_version">
({props.track.version})
</span>
)}
</div> </div>
<div className="music-track_artist"> <div className="music-track_artist">
<span> <span>
@ -233,6 +258,13 @@ const Track = (props) => {
</div> </div>
<div className="music-track_actions"> <div className="music-track_actions">
{trackDuration && (
<div className="music-track_play_duration">
<Icons.FiClock />
{secondsToIsoTime(trackDuration)}
</div>
)}
<antd.Dropdown <antd.Dropdown
menu={{ menu={{
items: moreMenuItems, items: moreMenuItems,
@ -242,11 +274,9 @@ const Track = (props) => {
open={moreMenuOpened} open={moreMenuOpened}
trigger={["click"]} trigger={["click"]}
> >
<antd.Button <div className="music-track_more-menu">
type="ghost" <Icons.IoMdMore />
size="large" </div>
icon={<Icons.IoMdMore />}
/>
</antd.Dropdown> </antd.Dropdown>
</div> </div>
</div> </div>

View File

@ -49,6 +49,11 @@ html {
.music-track_orderIndex { .music-track_orderIndex {
opacity: 0; opacity: 0;
} }
.music-track_play_duration {
opacity: 1;
width: fit-content;
}
} }
} }
} }
@ -113,6 +118,13 @@ html {
.music-track_play { .music-track_play {
position: relative; position: relative;
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
transition: all 150ms ease-in-out; transition: all 150ms ease-in-out;
cursor: pointer; cursor: pointer;
@ -200,13 +212,31 @@ html {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 75%;
color: var(--text-color); color: var(--text-color);
.music-track_titles {
display: flex;
flex-direction: row;
align-items: center;
gap: 5px;
.music-track_title { .music-track_title {
display: flex;
flex-direction: row;
align-items: center;
font-size: 1rem; font-size: 1rem;
//font-family: "Space Grotesk", sans-serif; gap: 5px;
}
.music-track_version {
font-size: 0.8rem;
opacity: 0.8;
}
} }
.music-track_artist { .music-track_artist {
@ -225,10 +255,27 @@ html {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 10px; gap: 5px;
margin-left: auto; margin-left: auto;
color: var(--text-color); color: var(--text-color);
.music-track_play_duration {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 5px;
font-size: 0.8rem;
}
.music-track_more-menu {
padding: 10px;
cursor: pointer;
}
} }
} }