Skip to content

Commit

Permalink
fix: 歌单创建
Browse files Browse the repository at this point in the history
  • Loading branch information
GuMengYu committed Nov 1, 2023
1 parent c87fcee commit a2f0ec5
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 37 deletions.
2 changes: 1 addition & 1 deletion electron/main/core/config/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let storeSize: {

} = {
width: 1099,
height: 740,
height: 700,
}
initWindowSize()
function initWindowSize() {
Expand Down
4 changes: 2 additions & 2 deletions electron/main/core/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export function createElectronMenu(window: BrowserWindow) {
{ role: 'cut', label: '剪切' },
{ role: 'copy', label: '复制' },
{ role: 'paste', label: '粘贴' },
// { role: 'delete', label: '删除' },
// { role: 'selectAll', label: '全选' },
{ role: 'delete', label: '删除' },
{ role: 'selectAll', label: '全选' },
{
label: '搜索',
accelerator: 'CmdOrCtrl+F',
Expand Down
2 changes: 1 addition & 1 deletion electron/main/core/util/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface StoreType {
const store = new Store<StoreType>({
defaults: {
windowSize: {
height: 740,
height: 700,
width: 1099,
},
windowPosition: null,
Expand Down
4 changes: 2 additions & 2 deletions electron/main/core/windowManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { StoreType } from './util/store'
import store from './util/store'

export const WindowDefaultSize = {
height: 740,
height: 700,
width: 1099,
minWidth: 144,
minHeight: 144,
Expand All @@ -25,7 +25,7 @@ const defaultBrowserOptions: BrowserWindowConstructorOptions = {
// show: false,
frame: !(is.windows() || is.linux()),
width: 1099,
height: 740,
height: 700,
// vibrancy: 'ultra-dark',
// visualEffectState: 'active',
// transparent: true,
Expand Down
34 changes: 23 additions & 11 deletions src/components/nowPlaying/NowPlayingList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Modal from '@mui/material/Modal'
import { Box, IconButton, Typography, useTheme } from '@mui/material'
import { Box, IconButton, Tooltip, Typography, useTheme } from '@mui/material'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { css, cx } from '@emotion/css'
import type { VirtuosoHandle } from 'react-virtuoso'
Expand All @@ -10,10 +10,11 @@ import Fade from '@mui/material/Fade'
import { alpha } from '@mui/material/styles'
import { useNavigate } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import ClearAllIcon from '@mui/icons-material/ClearAll'
import { useAppStore } from '@/store/app'
import { playQueueStore } from '@/store/playQueue'
import type { Track, TrackSource } from '@/types'
import { sizeOfImage } from '@/util/fn'
import { sizeOfImage, sleep } from '@/util/fn'
import Wave from '@/components/Wave'
import { usePlayer, usePlayerControl } from '@/hooks/usePlayer'
import { Track as TrackType } from '@/types'
Expand Down Expand Up @@ -276,16 +277,18 @@ function NowPlayingTrackList({ onClose }: { onClose: () => void }) {

function NowPlayingList() {
const { showNowPlayingList, toggleNowPlayingList } = useAppStore()
const { clearQueue } = playQueueStore()
const theme = useTheme()
const { t } = useTranslation()

const onClose = useCallback(() => {
toggleNowPlayingList(false)
}, [])
// useEffect(() => {
// if (showNowPlayingList) {
// console.log('open now playing list')
// }
// }, [showNowPlayingList]);
const onClear = useCallback(async () => {
clearQueue()
await sleep(200)
toggleNowPlayingList(false)
}, [])
return (
<Modal open={showNowPlayingList} onClose={onClose} sx={{
'&:focus-visible': {
Expand All @@ -307,10 +310,19 @@ function NowPlayingList() {
}}>
<div className='flex flex-col items-center w-1/2 relative'>
<NowPlayingTrackList onClose={onClose}/>
<IconButton onClick={onClose} sx={{
mt: 3,
bgcolor: `${theme.palette.primary.main}36`,
}} size='large'><CloseIcon/></IconButton>
<div className='mt-4 relative flex justify-center w-full items-center'>
<IconButton onClick={onClose} sx={{
bgcolor: alpha(theme.palette.primary.main, 0.35),
}} size='large'><CloseIcon/></IconButton>
<Tooltip title={t`common.clear_queue`} placement='top'>
<IconButton onClick={onClear} sx={{
position: 'absolute',
right: 0,
}}><ClearAllIcon/>
</IconButton>
</Tooltip>
</div>

</div>
</Box>
</Fade>
Expand Down
1 change: 1 addition & 0 deletions src/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"pause": "Pause",
"reload": "Reload",
"delete": "Delete",
"clear_queue": "Clear the queue",
"open_search": "Open Search",
"sign_in": "Sign In",
"sign_out": "Sign Out",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
"add_all_to_playlist": "收藏全部",
"pause": "暂停",
"delete": "删除",
"clear_queue": "清空队列",
"open_search": "打开搜索",
"sign_in": "登录",
"sign_out": "登出",
Expand Down
117 changes: 114 additions & 3 deletions src/pages/Library.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Box, Button, Card, Typography, useTheme } from '@mui/material'
import { memo, useEffect, useState } from 'react'
import {
Box,
Button,
Card, Checkbox, Dialog,
IconButton, TextField,
Tooltip,
Typography,
useTheme,
} from '@mui/material'
import { memo, useCallback, useEffect, useState } from 'react'

import { useNavigate } from 'react-router-dom'
import { sampleSize } from 'lodash'
Expand All @@ -9,6 +17,10 @@ import HistoryIcon from '@mui/icons-material/History'
import PodcastsIcon from '@mui/icons-material/Podcasts'
import ThumbUpAltIcon from '@mui/icons-material/ThumbUpAlt'
import { useTranslation } from 'react-i18next'
import { alpha } from '@mui/material/styles'
import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined'
import PlaylistAddIcon from '@mui/icons-material/PlaylistAdd'
import { useSnackbar } from 'notistack'
import MYTabs from '@/components/Tabs'
import PageTransition from '@/components/PageTransition'
import GridRow from '@/components/GridRow'
Expand All @@ -27,6 +39,7 @@ import { getSongData } from '@/api/song'
import { useReplacePlayQueue } from '@/hooks/usePlayQueue'
import { getTrackList } from '@/api/music'
import Col from '@/components/Col'
import { createPlaylist } from '@/api/playlist'

const AlbumCovers = memo(({ tracks }: { tracks: Track[] }) => {
const navigate = useNavigate()
Expand All @@ -46,6 +59,104 @@ const AlbumCovers = memo(({ tracks }: { tracks: Track[] }) => {
)
})

function CreatePlaylist() {
const theme = useTheme()
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const onClose = useCallback(() => {
setOpen(false)
}, [])
return <>
<Tooltip title={t`main.playlist.new`} placement='left'>
<IconButton
sx={{
bgcolor: alpha(theme.palette.tertiaryContainer.main, theme.palette.action.activatedOpacity),
}}
color={'tertiary' as 'primary'}
size='small'
onClick={() => setOpen(true)}
>
<AddCircleOutlineOutlinedIcon fontSize='small' />
</IconButton>
</Tooltip>
<CreateDialog open={open} onClose={onClose} />
</>
}

function CreateDialog({ open, onClose }: { open: boolean; onClose: () => void }) {

const theme = useTheme()
const { refreshPlaylist } = useUserStore()
const { t } = useTranslation()
const { enqueueSnackbar } = useSnackbar()
const [playlist, setPlaylist] = useState({
playlistName: '',
playlistPrivate: false,
})
useEffect(() => {
if (!open) {
setPlaylist({
playlistPrivate: false,
playlistName: '',
})
}
return () => {
setPlaylist({
playlistPrivate: false,
playlistName: '',
})
}
}, [open])

async function createNewPlaylist() {
try {
await createPlaylist({
name: playlist.playlistName,
privacy: playlist.playlistPrivate ? 10 : 0,
})
enqueueSnackbar('创建成功', { variant: 'success' })
refreshPlaylist()
onClose()
}
catch (e) {
enqueueSnackbar('something_wrong', { variant: 'error' })
}
}
return <Dialog sx={{
'& .MuiPaper-root': {
borderRadius: 8,
},
}} open={open} onClose={onClose}>
<Box className='pt-5 pb-4 px-2 flex flex-col' sx={{
bgcolor: theme.palette.surfaceVariant.main,
color: theme.palette.onSurfaceVariant.main,
minWidth: 300,
}}>
<div className='flex flex-col items-center mb-4 gap-1'>
<PlaylistAddIcon />
<Typography variant='body1'>创建新歌单</Typography>
</div>

<div className='px-3'>
<TextField className='w-full' variant='outlined' label="歌单名" value={playlist.playlistName} onChange={(e: any) => {
setPlaylist(state => ({
...state,
playlistName: e.target.value,
}))
}} />
</div>
<div className='flex items-center'>
<Checkbox />
<Typography variant='caption'>{'私人歌单'}</Typography>
</div>
<div className='flex justify-end'>
<Button variant='text' onClick={onClose}>取消</Button>
<Button variant='text' onClick={createNewPlaylist}>确定</Button>
</div>
</Box>
</Dialog>
}

function ArtistPanel() {
const { data } = useUserArtists()
return <GridRow>
Expand All @@ -58,7 +169,7 @@ function PlaylistPanel() {
const { t } = useTranslation()
const { createdPlaylist, subscribePlaylist } = useMyPlaylist()
return <div className='flex flex-col gap-4'>
<Col title={t`main.nav.created_list`} variant='body1'>
<Col title={t`main.nav.created_list`} variant='body1' more={<CreatePlaylist />}>
<GridRow>
{
createdPlaylist?.map(playlist => (<Cover key={playlist.id} type='playlist' data={playlist} />))
Expand Down
9 changes: 6 additions & 3 deletions src/pages/detail/Playlist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { sub } from '@/api/music'
import { deletePlayList } from '@/api/playlist'
import { PlayOutlinedIcon } from '@/components/icons/icons'
import useVirtualListScroll from '@/hooks/useVirtualListScroll'
import { useUserStore } from '@/store/user'

const PlayListHeader = memo(({ playlist, cover }: { playlist: Playlist | undefined; cover?: string }) => {
const theme = useTheme()
Expand All @@ -46,6 +47,7 @@ const PlayListHeader = memo(({ playlist, cover }: { playlist: Playlist | undefin
const tracksDt = playlist?.tracks?.reduce((p, c: any) => p + c.dt, 0)

const { openContextMenu } = useContextMenu()
const { refreshPlaylist } = useUserStore()
const confirm = useConfirm()
const { isCreatedPlaylist, isMyFavList } = useMyPlaylist()
const { replaceQueueAndPlay } = useReplacePlayQueue()
Expand Down Expand Up @@ -79,10 +81,11 @@ const PlayListHeader = memo(({ playlist, cover }: { playlist: Playlist | undefin
dialogProps: { maxWidth: 'xs' },
}).then(async () => {
const { code, message } = await deletePlayList(playlist.id)
if (code === 200)
if (code === 200) {
enqueueSnackbar('已删除', { variant: 'success' })
else
enqueueSnackbar(message, { variant: 'error' })
refreshPlaylist()
}
else {enqueueSnackbar(message, { variant: 'error' })}
})
}
const handleMore = useCallback((e: React.MouseEvent<HTMLElement>) => {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function Header() {
height: 78,
zIndex: 2,
gridArea: 'main',
pr: 2,
pr: 1.5,
position: 'relative',
}}
>
Expand Down
1 change: 1 addition & 0 deletions src/pages/layout/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default function Main({
<Box
sx={{
minHeight: 'calc(((100vh - 64px) - 90px) - 519px)',
pr: inDetail ? 0 : 0.5,
}}
>
<AnimatePresence mode='wait'>
Expand Down
1 change: 1 addition & 0 deletions src/pages/layout/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function SearchBar() {
sx={{ display: 'flex', alignItems: 'center', bgcolor: theme.palette.surfaceVariant.main, borderRadius: 16, width: 240, height: 42 }}
>
<InputBase
autoFocus
sx={{ ml: 2, flex: 1, fontSize: 14 }}
placeholder="Search Anything"
inputProps={{ 'aria-label': 'search anything' }}
Expand Down
5 changes: 4 additions & 1 deletion src/pages/modal/Md3Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { DialogProps } from '@mui/material'
import { Dialog, styled } from '@mui/material'
import { memo } from 'react'

export default function Md3Dialog(props: DialogProps) {
function Md3Dialog(props: DialogProps) {
const MdDialog = styled(Dialog)(({ theme }) => ({
'& .MuiPaper-root': {
borderRadius: 24,
Expand All @@ -12,3 +13,5 @@ export default function Md3Dialog(props: DialogProps) {
{props.children}
</MdDialog>
}

export default memo(Md3Dialog)
Loading

0 comments on commit a2f0ec5

Please sign in to comment.