Skip to content

Commit

Permalink
feat: add use songlist ui and logic
Browse files Browse the repository at this point in the history
  • Loading branch information
uniquemo committed May 12, 2020
1 parent 80de017 commit 0fbe910
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 14 deletions.
24 changes: 23 additions & 1 deletion src/apis/songlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type GetSonglistsFn = (params: IGetSonglistsRequest) => Promise<{ playlists: ISo
type GetSonglistCatsFn = () => Promise<IGetSonglistCatsResponse>
type GetSonglistHotCatsFn = () => Promise<ICategory[]>
type GetHighQualitySonglistFn = (cat?: string) => Promise<ISonglist>
type GetUserSonglistFn = (uid: number) => Promise<{ create: ISonglist[], collect: ISonglist[] }>

const getSonglistDetail: GetSonglistDetailFn = async (id) => {
const response = await axios({
Expand Down Expand Up @@ -82,10 +83,31 @@ const getHighQualitySonglist: GetHighQualitySonglistFn = async (cat = '全部')
return response?.playlists?.[0]
}

const getUserSonglist: GetUserSonglistFn = async (uid) => {
const response = await axios({
method: 'get',
url: '/user/playlist',
params: {
uid,
limit: PAGE_SIZE
}
})

const playlist: ISonglist[] = response.playlist || []
const create = playlist.filter(({ creator }) => uid === creator.userId)
const collect = playlist.filter(({ creator }) => uid !== creator.userId)

return {
create,
collect
}
}

export default {
getSonglistDetail,
getSonglists,
getSonglistCats,
getSonglistHotCats,
getHighQualitySonglist
getHighQualitySonglist,
getUserSonglist
}
1 change: 1 addition & 0 deletions src/apis/types/business.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface ISonglist {
creator: {
avatarUrl: string,
nickname: string,
userId: number
},
description: string,
highQuality: boolean,
Expand Down
6 changes: 3 additions & 3 deletions src/components/Layout/Sidebar/Menus/style.module.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@value colors: "~styles/colors.module.css";
@value grey from colors;
@value grey, red from colors;

.tabs {
color: rgb(77, 77, 77);
Expand All @@ -14,11 +14,11 @@
}

.tab:hover {
background-color: rgb(227, 227, 227);
background-color: #e3e3e3;
}

.active {
color: rgb(208, 58, 54);
color: red;
}
}

Expand Down
46 changes: 46 additions & 0 deletions src/components/Layout/Sidebar/Songlist/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react'
import { useHistory, useRouteMatch } from 'react-router-dom'
import cn from 'classnames'

import { LogStateContext } from 'reducers/log'
import { ISonglist } from 'apis/types/business'
import ROUTES from 'constants/routes'
import styles from './style.module.css'

interface IProps {
title: string,
data?: ISonglist[]
}

const { useContext } = React

const Songlist: React.FC<IProps> = ({ title, data }) => {
const history = useHistory()
const routeMatch = useRouteMatch<{ songlistId: string }>(ROUTES.SONG_LIST_DETAIL)
const logState = useContext(LogStateContext)

const handleClick = (id: number) => history.push(`${ROUTES.SONG_LISTS}/${id}`)

return (
<div className={styles.root}>
<div className={styles.title}>{title}</div>
<div className={styles.content}>
{data?.map(({ id, name }) => {
const isActive = routeMatch && Number(routeMatch.params.songlistId) === id
return (
<div
key={id}
className={cn(styles.item, isActive && 'active')}
title={name}
onClick={() => handleClick(id)}
>
{name.replace(logState.user.profile.nickname, '我')}
</div>
)
})}
</div>
</div>
)
}

export default Songlist
21 changes: 21 additions & 0 deletions src/components/Layout/Sidebar/Songlist/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.title {
padding: 0 20px;
margin-bottom: 5px;
font-size: 0.8em;
color: grey;
}

.content {
.item {
padding: 8px 20px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
cursor: default;
font-size: 0.9em;

&:hover {
background-color: #e3e3e3;
}
}
}
27 changes: 25 additions & 2 deletions src/components/Layout/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@ import React from 'react'
import { Icon, Popover, Menu, MenuItem } from '@blueprintjs/core'

import Menus from './Menus'
import Songlist from './Songlist'
import LoginDialog from './LoginDialog'
import authApis from 'apis/auth'
import songlistApis from 'apis/songlist'
import useAsyncFn from 'hooks/useAsyncFn'
import { LogStateContext, LogDispatchContext, ACTIONS } from 'reducers/log'
import styles from './style.module.css'

const { useState, useContext } = React
const { useState, useContext, useEffect } = React

const Sidebar = () => {
const dispatch = useContext(LogDispatchContext)
const logState = useContext(LogStateContext)
const { isLogined, user } = logState

const [showLoginDialog, setShowLoginDialog] = useState(false)
const [logoutState, logoutFn] = useAsyncFn(authApis.logout)
const [songlistState, getUserSonglistFn] = useAsyncFn(songlistApis.getUserSonglist)

useEffect(() => {
if (isLogined) {
getUserSonglistFn(logState.user.userId)
}
}, [isLogined])

const handleNameClick = () => setShowLoginDialog(true)
const handleLoginDialogClose = () => setShowLoginDialog(false)
Expand Down Expand Up @@ -53,7 +63,20 @@ const Sidebar = () => {
)}
</div>

<Menus />
<div className={styles.content}>
<Menus />
{!songlistState.loading && isLogined && (
<>
<div className={styles.block}>
<Songlist title='创建的歌单' data={songlistState.value?.create} />
</div>

<div className={styles.block}>
<Songlist title='收藏的歌单' data={songlistState.value?.collect} />
</div>
</>
)}
</div>

<LoginDialog
isOpen={showLoginDialog}
Expand Down
16 changes: 13 additions & 3 deletions src/components/Layout/Sidebar/style.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@

.root {
width: sidebarWidth;
height: 100%;
padding: headerHeight 0 footerHeight;
height: calc(100% - footerHeight);
padding-top: headerHeight;
display: flex;
flex-direction: column;
background-color: rgb(234, 234, 234);
background-color: #eaeaea;
overflow: hidden;
}

.content {
height: 100%;
overflow: scroll;
}

.user {
Expand Down Expand Up @@ -40,3 +46,7 @@
cursor: default;
}
}

.block {
margin-bottom: 20px;
}
2 changes: 1 addition & 1 deletion src/constants/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const MV: string = `${VIDEOS}/mv`
const SEARCH: string = '/search'

const SONG_LISTS: string = '/songlists'
const SONG_LIST_DETAIL: string = `${SONG_LISTS}/:id`
const SONG_LIST_DETAIL: string = `${SONG_LISTS}/:songlistId`

const DOWNLOAD: string = '/download'
const CLOUD: string = '/cloud'
Expand Down
4 changes: 2 additions & 2 deletions src/pages/SonglistDetail/BasicInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ const BasicInfo: React.FC<IProps> = ({ data, onPlayAll }) => {
<div className={styles.detail}>
<div>
<span className={styles.label}>标签: </span>
{data?.tags.join(' / ')}
{data?.tags.join(' / ') || '--'}
</div>
<div>
<span className={styles.label}>歌曲数: </span>{data?.trackCount}&nbsp;&nbsp;
<span className={styles.label}>播放数: </span>{formatNum(data?.playCount)}
</div>
<div>
<span className={styles.label}>简介: </span>
{data?.description}
{data?.description || '--'}
</div>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/pages/SonglistDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ const TABS = [
const SonglistDetail = () => {
const dispatch = useContext(PlayMusicDispatchContext)
const params = useParams<IDictionary<string>>()
const { songlistId } = params

const [state, getSonglistDetailFn] = useAsyncFn(songlistApis.getSonglistDetail)
const { value: result, loading } = state

const songs = result?.songs as IMusic[]

useEffect(() => {
getSonglistDetailFn(Number(params.id))
}, [])
getSonglistDetailFn(Number(songlistId))
}, [songlistId])

const playAll = (autoPlay?: boolean) => {
const list = songs.map((item) => {
Expand Down

0 comments on commit 0fbe910

Please sign in to comment.