added play page

This commit is contained in:
SrGooglo 2023-02-24 14:41:21 +00:00
parent 91eb6647dc
commit 21e0057493
2 changed files with 254 additions and 42 deletions

View File

@ -2,20 +2,35 @@ import React from "react"
import * as antd from "antd"
import classnames from "classnames"
import { ImageViewer } from "components"
import moment from "moment"
import { Icons } from "components/Icons"
import PlaylistsModel from "models/playlists"
import "./index.less"
const PlaylistItem = ({ playlist }) => {
return <div>
Playlist Tracks
</div>
}
const TrackItem = ({ track }) => {
return <div>
Track
const TrackItem = (props) => {
return <div className="track_item">
<div className="track_item_actions">
<antd.Button
type="primary"
shape="circle"
icon={<Icons.Play />}
onClick={props.onClick}
/>
</div>
<div className="track_item_cover">
<ImageViewer src={props.track.thumbnail} />
</div>
<div className="track_item_details">
<div className="track_item_title">
{props.track.title}
</div>
<div className="track_item_artist">
{props.track.artist}
</div>
</div>
</div>
}
@ -38,6 +53,19 @@ export default (props) => {
}
}
const handleOnClickTrack = (track) => {
// search index of track
const index = playlist.list.findIndex((item) => {
return item._id === track._id
})
if (index === -1) {
return
}
app.cores.player.startPlaylist(playlist.list, index)
}
React.useEffect(() => {
loadData()
}, [])
@ -46,20 +74,6 @@ export default (props) => {
return <antd.Skeleton active />
}
const renderComponent = () => {
switch (playlist.type) {
case "playlist": {
return <PlaylistItem playlist={playlist} />
}
case "track": {
return <TrackItem track={playlist} />
}
default: {
return <TrackItem track={playlist} />
}
}
}
return <div
className={
classnames("play", playlist.type)
@ -68,20 +82,60 @@ export default (props) => {
<div className="play_info_wrapper">
<div className="play_info">
<div className="play_info_cover">
<ImageViewer src={playlist?.cover ?? "/assets/no_song.png"} />
<ImageViewer src={playlist?.thumbnail ?? "/assets/no_song.png"} />
</div>
<div className="play_info_details">
<div className="play_info_title">
<h1>{playlist.title}</h1>
</div>
<div className="play_info_author">
{playlist.user.username}
<div className="play_info_description">
<h3>
{playlist.description}
</h3>
</div>
<div className="play_info_statistics">
<div className="play_info_statistics_item">
<p
onClick={() => {
app.navigation.goToAccount(playlist.user.username)
}}
>
<Icons.MdPerson />
Publised by <a>{playlist.user.username}</a>
</p>
</div>
<div className="play_info_statistics_item">
<p>
<Icons.MdLibraryMusic /> {playlist.list.length} Tracks
</p>
</div>
<div className="play_info_statistics_item">
<p>
<Icons.MdAccessTime /> Released on {moment(playlist.created_at).format("DD/MM/YYYY")}
</p>
</div>
</div>
</div>
</div>
</div>
{renderComponent()}
<div className="list">
<h1>
<Icons.MdPlaylistPlay /> Tracks
</h1>
{
playlist.list.map((item, index) => {
return <TrackItem
track={item}
onClick={() => handleOnClickTrack(item)}
/>
})
}
</div>
</div>
}

View File

@ -1,7 +1,7 @@
.play {
display: grid;
grid-template-columns: 1fr 50vw;
grid-template-columns: 30vw 1fr;
grid-template-rows: 1fr;
grid-column-gap: 20px;
grid-row-gap: 0px;
@ -15,49 +15,207 @@
width: 100%;
padding: 20px;
color: var(--text-color);
.play_info {
display: flex;
flex-direction: column;
align-self: center;
width: 30vw;
height: 100%;
padding: 20px;
background-color: var(--background-color-accent);
border-radius: 12px;
.play_info_cover {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
align-self: center;
width: 400px;
height: 400px;
background-color: black;
border-radius: 12px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 12px;
object-fit: cover;
}
}
.play_info_details {
margin-top: 20px;
padding: 20px;
.play_info_title {
font-size: 1.5rem;
font-family: "Space Grotesk", sans-serif;
h1 {
margin: 0;
}
word-break: break-all;
font-weight: 600;
margin-bottom: 10px;
}
.play_info_description {
font-size: 0.8rem;
font-weight: 400;
}
.play_info_statistics {
display: flex;
flex-direction: column;
margin-top: 20px;
background-color: var(--background-color-primary);
padding: 20px;
border-radius: 8px;
.play_info_statistics_item {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 10px;
h1,
h2,
h3,
h4,
h5,
h6,
p,
span {
margin: 0;
}
.play_info_statistics_item_icon {
margin-right: 10px;
}
.play_info_statistics_item_text {
font-size: 0.8rem;
font-weight: 400;
}
&:last-child {
margin-bottom: 0;
}
}
}
}
}
}
.list {
display: flex;
flex-direction: column;
color: var(--text-color);
padding: 0 30px;
}
}
.track_item {
display: flex;
flex-direction: row;
align-items: center;
padding: 10px;
margin-bottom: 10px;
border-radius: 8px;
background-color: var(--background-color-accent);
cursor: pointer;
.track_item_actions {
margin-right: 10px;
.ant-btn {
svg {
margin: 0 !important;
background-color: transparent;
}
margin-right: 10px;
&:last-child {
margin-right: 0;
}
}
}
.track_item_cover {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: black;
border-radius: 12px;
overflow: hidden;
width: 50px;
height: 50px;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.track_item_details {
display: flex;
flex-direction: column;
margin-left: 10px;
.track_item_title {
font-size: 1rem;
font-family: "Space Grotesk", sans-serif;
}
.track_item_artist {
font-size: 0.8rem;
}
}
&:last-child {
margin-bottom: 0;
}
}