Skip to content

Commit

Permalink
feat: add Recommendation, Latest music logic
Browse files Browse the repository at this point in the history
  • Loading branch information
uniquemo committed May 3, 2020
1 parent 8816f23 commit 1e8fbcd
Show file tree
Hide file tree
Showing 15 changed files with 263 additions and 24 deletions.
15 changes: 13 additions & 2 deletions src/apis/personalized.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import axios from 'helpers/axios'
import { IGetPersonalizedSongListRequest, ISongList } from './types/personalized'
import { IGetPersonalizedSongListRequest, ISongList, IMusic } from './types/personalized'

type GetPersonalizedSongListFn = (params: IGetPersonalizedSongListRequest) => Promise<ISongList[]>
type GetPersonalizedNewMusicFn = () => Promise<IMusic[]>

const getPersonalizedSongList: GetPersonalizedSongListFn = async ({ limit }) => {
const response = await axios({
Expand All @@ -15,6 +16,16 @@ const getPersonalizedSongList: GetPersonalizedSongListFn = async ({ limit }) =>
return response.result || []
}

const getPersonalizedNewMusic: GetPersonalizedNewMusicFn = async () => {
const response = await axios({
method: 'get',
url: '/personalized/newsong'
})

return response.result
}

export default {
getPersonalizedSongList
getPersonalizedSongList,
getPersonalizedNewMusic
}
23 changes: 23 additions & 0 deletions src/apis/types/personalized.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,26 @@ export interface ISongList {
trackNumberUpdateTime: number,
type: number
}

export interface IArtist {
albumSize: number,
id: number,
img1v1Id: number,
img1v1Url: string,
musicSize: number,
name: string,
picId: number,
picUrl: string,
topicPerson: number
}

export interface IMusic {
alg: string,
canDislike: boolean,
id: number,
name: string,
picUrl: string,
song: {
artists: IArtist[]
}
}
19 changes: 19 additions & 0 deletions src/components/PlayIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react'
import { Icon } from '@blueprintjs/core'
import cn from 'classnames'

import styles from './style.module.css'

interface IProps {
className?: string
}

const PlayIcon: React.FC<IProps> = ({ className }) => {
return (
<div className={cn(styles.root, className)}>
<Icon icon='play' />
</div>
)
}

export default PlayIcon
13 changes: 13 additions & 0 deletions src/components/PlayIcon/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@value colors: "~styles/colors.module.css";
@value red from colors;

.root {
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.8);
color: red;
}
45 changes: 45 additions & 0 deletions src/pages/Discovery/Recommendation/LatestMusic/MusicItem/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react'
import cn from 'classnames'

import PlayIcon from 'components/PlayIcon'
import { IArtist } from 'apis/types/personalized'

import styles from './style.module.css'

interface IProps {
name: string,
picUrl: string,
artists: IArtist[],
index: number
}

const MusicItem: React.FC<IProps> = ({ name, picUrl, artists, index }) => {
const hasBorderBottom = [4, 9].indexOf(index) > -1

return (
<div className={cn(styles.root, hasBorderBottom ? styles.borderBottom : '')}>
<div className={styles.pic}>
<img src={`${picUrl}?param=60y60`} />
<PlayIcon className={styles.playIcon} />
</div>
<div className={styles.order}>
{index < 9 ? `0${index + 1}` : index + 1}
</div>
<div className={styles.info}>
<div className={styles.name}>
{name}
</div>
<div className={styles.singers}>
{artists?.map(({ name }, index) =>
(index !== artists?.length - 1
? <div key={name}><span className={styles.singer}>{name}</span><span className={styles.slash}>/</span></div>
: <span key={name} className={styles.singer}>{name}</span>
)
)}
</div>
</div>
</div>
)
}

export default MusicItem
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@value colors: "~styles/colors.module.css";
@value nameColor, tipsColor from colors;

.root {
display: flex;
align-items: center;
padding: 10px 0;
border-top: 1px solid #f5f5f5;
}

.borderBottom {
border-bottom: 1px solid #f5f5f5;
}

.pic {
width: 60px;
height: 60px;
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.5);
position: relative;
margin-right: 10px;
cursor: pointer;

img {
border-radius: 5px;
}

.playIcon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}

.order {
margin-right: 10px;
font-size: 0.9em;
color: tipsColor;
}

.info {
.name {
color: nameColor;
}

.singers {
display: flex;
align-items: center;
color: tipsColor;
}

.singer {
margin-top: 5px;
font-size: 0.9em;
cursor: pointer;

&:hover {
color: #797979;
}
}

.slash {
margin: 0 5px;
}
}
49 changes: 48 additions & 1 deletion src/pages/Discovery/Recommendation/LatestMusic/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,55 @@
import React from 'react'
import { Spinner } from '@blueprintjs/core'

import LinkTitle from 'components/LinkTitle'
import MusicItem from './MusicItem'

import ROUTES from 'constants/routes'
import useAsyncFn from 'hooks/useAsyncFn'
import personalizedApis from 'apis/personalized'

import styles from './style.module.css'

const { useEffect } = React

const LatestMusic = () => {
const [state, getPersonalizedNewMusicFn] = useAsyncFn(personalizedApis.getPersonalizedNewMusic)
const { value: music = [], loading } = state

useEffect(() => {
getPersonalizedNewMusicFn()
}, [])

return (
<div>LatestMusic</div>
<div className={styles.root}>
<LinkTitle title='最新音乐' route={ROUTES.LATEST_MUSIC} />
{loading ? <Spinner /> : (
<div className={styles.content}>
<div className={styles.block}>
{music.slice(0, 5).map(({ name, picUrl, song }, index) => (
<MusicItem
key={name}
index={index}
name={name}
picUrl={picUrl}
artists={song?.artists}
/>
))}
</div>
<div className={styles.block}>
{music.slice(5, 10).map(({ name, picUrl, song }, index) => (
<MusicItem
key={name}
index={index + 5}
name={name}
picUrl={picUrl}
artists={song?.artists}
/>
))}
</div>
</div>
)}
</div>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.content {
display: flex;
justify-content: space-between;
}

.block {
width: 48%;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { Icon } from '@blueprintjs/core'

import PlayIcon from 'components/PlayIcon'
import styles from './style.module.css'

interface IProps {
Expand All @@ -18,9 +19,7 @@ const SongItem: React.FC<IProps> = ({ name, playCount, picUrl }) => {
<Icon icon='play' />
{playCount}
</div>
<div className={styles.playIcon}>
<Icon icon='play' />
</div>
<PlayIcon className={styles.playIcon} />
</div>
<div className={styles.name}>{name}</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@value colors: "~styles/colors.module.css";
@value red from colors;
@value nameColor from colors;

.root {
position: relative;
Expand Down Expand Up @@ -36,14 +36,6 @@
position: absolute;
bottom: 10px;
right: 10px;
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
color: red;
visibility: hidden;
}

Expand All @@ -55,5 +47,5 @@
.name {
margin-top: 5px;
font-size: 0.95em;
color: #5d5d5d;
color: nameColor;
}
6 changes: 3 additions & 3 deletions src/pages/Discovery/Recommendation/SongList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import { Spinner } from '@blueprintjs/core'

import LinkTitle from 'components/LinkTitle'
import SongItem from './SongItem'
import ROUTES from 'constants/routes'

import ROUTES from 'constants/routes'
import useAsyncFn from 'hooks/useAsyncFn'
import personalizedApis from 'apis/personalized'
import styles from './style.module.css'

const { useEffect } = React

const SongList = () => {
const [getPersonalizedSongListState, personalizedSongListFn] = useAsyncFn(personalizedApis.getPersonalizedSongList)
const { value: songList = [], loading: isGettingSongList } = getPersonalizedSongListState || {}
const [state, personalizedSongListFn] = useAsyncFn(personalizedApis.getPersonalizedSongList)
const { value: songList = [], loading: isGettingSongList } = state || {}

useEffect(() => {
personalizedSongListFn({ limit: 10 })
Expand Down
19 changes: 15 additions & 4 deletions src/pages/Discovery/Recommendation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,21 @@ import styles from './style.module.css'
const Recommendation = () => {
return (
<div className={styles.root}>
<Slider />
<SongList />
<LatestMusic />
<MV />
<div className={styles.block}>
<Slider />
</div>

<div className={styles.block}>
<SongList />
</div>

<div className={styles.block}>
<LatestMusic />
</div>

<div className={styles.block}>
<MV />
</div>
</div>
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/pages/Discovery/Recommendation/style.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.root {
padding: 10px 0;
}

.block {
margin-bottom: 50px;
}
1 change: 0 additions & 1 deletion src/pages/Discovery/style.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
width: 94%;
max-width: contentMaxWidth;
margin: 0 auto;
background-color: #ccc;
}
2 changes: 2 additions & 0 deletions src/styles/colors.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@value red: #c7332f;
@value grey: #7d7d7d;
@value black: #000;
@value nameColor: #5d5d5d;
@value tipsColor: #bababa;

0 comments on commit 1e8fbcd

Please sign in to comment.