Skip to content

Commit

Permalink
feat: add MusciDetail component, comment, simi songlist, simi songs l…
Browse files Browse the repository at this point in the history
…ogic
  • Loading branch information
uniquemo committed May 13, 2020
1 parent a4d1c1d commit a8e11bd
Show file tree
Hide file tree
Showing 31 changed files with 1,118 additions and 57 deletions.
63 changes: 63 additions & 0 deletions src/apis/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import axios from 'helpers/axios'

enum COMMENT_TYPE {
MUSIC = 0,
MV = 1,
SONGLIST = 2,
ALBUM = 3,
RADIO_STATION = 4,
VIDEO = 5
}

interface ILikeUnlikeCommentRequest {
likeOrUnlike: number,
type?: COMMENT_TYPE,
id: number,
commentId: number
}

type Params = Omit<ILikeUnlikeCommentRequest, 'likeOrUnlike'>

type LikeUnlikeCommentFn = (params: ILikeUnlikeCommentRequest) => Promise<any>
type LikeCommentFn = (params: Params, callback?: Function) => Promise<any>
type UnlikeCommentFn = (params: Params, callback?: Function) => Promise<any>

const likeUnlikeComment: LikeUnlikeCommentFn = async ({ likeOrUnlike, type, id, commentId }) => {
const response = await axios({
method: 'get',
url: '/comment/like',
params: {
id,
type,
t: likeOrUnlike,
cid: commentId
}
})
return response
}

const likeComment: LikeCommentFn = async ({ id, commentId, type = COMMENT_TYPE.MUSIC }) => {
const response = await likeUnlikeComment({
likeOrUnlike: 1,
type,
id,
commentId
})
return response
}

const unlikeComment: UnlikeCommentFn = async ({ id, commentId, type = COMMENT_TYPE.MUSIC }) => {
const response = await likeUnlikeComment({
likeOrUnlike: 2,
type,
id,
commentId
})
return response
}

export default {
likeUnlikeComment,
likeComment,
unlikeComment
}
84 changes: 82 additions & 2 deletions src/apis/song.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import axios from 'helpers/axios'
import { IMyMusic, IMusic } from 'apis/types/business'
import { IMyMusic, IMusic, ISonglist } from 'apis/types/business'
import { IComment } from 'apis/types/comment'

export enum SONG_TYPE {
ALL = 0,
Expand All @@ -9,9 +10,30 @@ export enum SONG_TYPE {
KOREAN = 16
}

interface IParams {
id: number,
offset?: number,
limit?: number
}

interface IGetCommentsResponse {
comments: IComment[],
hotComments?: IComment[],
isMusician: boolean,
more: boolean,
moreHot: boolean,
topComments: IComment[],
total: number,
userId: number
}

type GetSongDetailFn = (ids: number[]) => Promise<any>
type GetTopSongsFn = (type?: SONG_TYPE) => Promise<IMyMusic[]>
type GetRecommendSongsFn = () => Promise<IMusic[]>
type GetSimiSonglistFn = (params: IParams) => Promise<ISonglist[]>
type GetgetSimiSongFn = (params: IParams) => Promise<IMusic[]>
type GetCommentsFn = (params: IParams) => Promise<IGetCommentsResponse>
type GetgetLyricFn = (id: number) => Promise<any>

const getSongDetail: GetSongDetailFn = async (ids) => {
const response = await axios({
Expand Down Expand Up @@ -46,8 +68,66 @@ const getRecommendSongs: GetRecommendSongsFn = async () => {
return response.recommend
}

const getSimiSonglist: GetSimiSonglistFn = async ({ id, offset, limit }) => {
const response = await axios({
method: 'get',
url: '/simi/playlist',
params: {
id,
offset,
limit
}
})

return response.playlists
}

const getSimiSong: GetgetSimiSongFn = async ({ id, offset, limit }) => {
const response = await axios({
method: 'get',
url: '/simi/song',
params: {
id,
offset,
limit
}
})

return response.songs
}

const getComments: GetCommentsFn = async ({ id, offset, limit }) => {
const response = await axios({
method: 'get',
url: '/comment/music',
params: {
id,
offset,
limit
}
})

return response
}

const getLyric: GetgetLyricFn = async (id) => {
const response = await axios({
method: 'get',
url: '/lyric',
params: {
id
}
})

return response
}

export default {
getSongDetail,
getTopSongs,
getRecommendSongs
getRecommendSongs,
getSimiSonglist,
getSimiSong,
getComments,
getLyric
}
29 changes: 29 additions & 0 deletions src/apis/types/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export interface IUser {
anonym: number,
authStatus: number,
avatarUrl: string,
nickname: string,
userId: number,
userType: number,
vipType: number
}

export interface IReply {
beRepliedCommentId: number,
content: string,
status: number,
user: IUser
}

export interface IComment {
beReplied: IReply[],
commentId: number,
commentLocationType: number,
content: string,
liked: boolean,
likedCount: number,
parentCommentId: number,
status: number,
time: number,
user: IUser
}
Binary file added src/assets/image/play-bar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/image/play-cd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions src/components/Comment/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react'
import { Icon } from '@blueprintjs/core'
import cn from 'classnames'

import { IComment } from 'apis/types/comment'
import { formatDatetime } from 'helpers/time'
import styles from './style.module.css'

interface IProps {
data: IComment,
onLikeChange: (comment: IComment) => void
}

const Comment: React.FC<IProps> = ({ data, onLikeChange }) => {
const { user, content, beReplied, time, likedCount, liked } = data

const likeUnlike = async () => {
await onLikeChange(data)
}

return (
<div className={styles.root}>
<div className={styles.avatar}>
<img src={`${user.avatarUrl}?param=35y35`} loading='lazy' />
</div>

<div className={styles.info}>
<div className={styles.comment}>
<span className={styles.nickname}>{user.nickname}: </span>
<span>{content}</span>
</div>

<div className={styles.reply}>
{beReplied.map(({ content, user }, index) => {
return (
<div className={styles.item} key={index}>
<span className={styles.nickname}>{user.nickname}: </span>
<span>{content}</span>
</div>
)
})}
</div>

<div className={styles.others}>
<div className={styles.time}>
{formatDatetime(time, true)}
</div>
<div className={styles.operations}>
<div className={cn(styles.like, liked && 'active')} onClick={likeUnlike}>
<Icon icon='thumbs-up' iconSize={14} />&nbsp;
{!!likedCount && <span>{likedCount}</span>}
</div>
</div>
</div>
</div>
</div>
)
}

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

.root {
display: flex;
}

.avatar {
width: 35px;
height: 35px;
margin-right: 20px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;

img {
border-radius: 50%;
}
}

.info {
flex: 1;
padding-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid #ededed;

.comment {
margin-bottom: 8px;
font-size: 0.95em;
}

.reply {
margin-bottom: 10px;
font-size: 0.9em;
.item {
width: 100%;
padding: 8px 10px;
border-radius: 3px;
background-color: #f0f0f0;
}
}

.nickname {
color: blue;
}

.others {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.9em;
color: tipsHoverColor;

.operations {
display: flex;

.like {
display: flex;
align-items: center;
cursor: pointer;
}
}
}
}
28 changes: 25 additions & 3 deletions src/components/Layout/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import { Icon, Tooltip } from '@blueprintjs/core'
import cn from 'classnames'

import Artists from 'components/Artists'
import AudioTimer from './AudioTimer'
Expand All @@ -8,18 +9,31 @@ import PlayRecord from './PlayRecord'
import PlayMode from './PlayMode'
import PlayOperations from './PlayOperations'
import PlayVolume from './PlayVolume'
import { PlayMusicStateContext } from 'reducers/playMusic'
import { PlayMusicStateContext, PlayMusicDispatchContext, ACTIONS } from 'reducers/playMusic'
import styles from './style.module.css'

const { useContext, useState } = React

const Footer = () => {
const [showPlayRecord, setShowPlayRecord] = useState(false)
const dispatch = useContext(PlayMusicDispatchContext)
const state = useContext(PlayMusicStateContext)
const { musicId, music } = state
const { musicId, music, showLyric } = state

const togglePlayRecord = () => setShowPlayRecord(!showPlayRecord)

const handleShowLyric = () => {
dispatch({
type: ACTIONS.SHOW_LYRIC
})
}

const handleHideLyric = () => {
dispatch({
type: ACTIONS.HIDE_LYRIC
})
}

return (
<div className={styles.root}>
{musicId ? (
Expand All @@ -29,7 +43,15 @@ const Footer = () => {
) : null}

<div className={styles.songWrap}>
<img src={music?.picUrl ? `${music?.picUrl}?param=40y40` : undefined} loading='lazy' />
<div className={cn(styles.pic, !showLyric && styles.showLyric)}>
<img src={music?.picUrl ? `${music?.picUrl}?param=40y40` : undefined} loading='lazy' />
{!showLyric && <div className={styles.mask} onClick={handleShowLyric}>
<Icon icon='double-chevron-up' />
</div>}
{showLyric && <div className={cn(styles.mask, styles.hideLyric)} onClick={handleHideLyric}>
<Icon icon='double-chevron-down' />
</div>}
</div>
<div>
<div className={styles.info}>
<div className={styles.name}>{`${music?.name || '--'} -`}</div>
Expand Down
Loading

0 comments on commit a8e11bd

Please sign in to comment.