mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-06 21:10:23 +00:00
feat: 新版webui
This commit is contained in:
124
napcat.webui/src/contexts/dialog.tsx
Normal file
124
napcat.webui/src/contexts/dialog.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
// Dialog Context
|
||||
import React from 'react'
|
||||
|
||||
import type { ModalProps } from '@/components/modal'
|
||||
import Modal from '@/components/modal'
|
||||
|
||||
export interface AlertProps {
|
||||
title?: React.ReactNode
|
||||
content: React.ReactNode
|
||||
size?: ModalProps['size']
|
||||
dismissible?: boolean
|
||||
onConfirm?: () => void
|
||||
}
|
||||
|
||||
export interface ConfirmProps {
|
||||
title?: React.ReactNode
|
||||
content: React.ReactNode
|
||||
size?: ModalProps['size']
|
||||
dismissible?: boolean
|
||||
onConfirm?: () => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export interface ModalItem extends ModalProps {
|
||||
id: number
|
||||
}
|
||||
|
||||
export interface DialogContextProps {
|
||||
alert: (config: AlertProps) => void
|
||||
confirm: (config: ConfirmProps) => void
|
||||
}
|
||||
|
||||
export interface DialogProviderProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export const DialogContext = React.createContext<DialogContextProps>({
|
||||
alert: () => {},
|
||||
confirm: () => {}
|
||||
})
|
||||
|
||||
const DialogProvider: React.FC<DialogProviderProps> = ({ children }) => {
|
||||
const [dialogs, setDialogs] = React.useState<ModalItem[]>([])
|
||||
const alert = (config: AlertProps) => {
|
||||
const { title, content, dismissible, onConfirm, size = 'md' } = config
|
||||
|
||||
setDialogs((before) => {
|
||||
const id = before[before.length - 1]?.id + 1 || 0
|
||||
|
||||
return [
|
||||
...before,
|
||||
{
|
||||
id,
|
||||
content,
|
||||
size,
|
||||
title,
|
||||
backdrop: 'blur',
|
||||
showCancel: false,
|
||||
dismissible: dismissible,
|
||||
onConfirm: () => {
|
||||
onConfirm?.()
|
||||
setTimeout(() => {
|
||||
setDialogs((before) => before.filter((item) => item.id !== id))
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
const confirm = (config: ConfirmProps) => {
|
||||
const {
|
||||
title,
|
||||
content,
|
||||
dismissible,
|
||||
onConfirm,
|
||||
onCancel,
|
||||
size = 'md'
|
||||
} = config
|
||||
|
||||
setDialogs((before) => {
|
||||
const id = before[before.length - 1]?.id + 1 || 0
|
||||
|
||||
return [
|
||||
...before,
|
||||
{
|
||||
id,
|
||||
content,
|
||||
size,
|
||||
title,
|
||||
backdrop: 'blur',
|
||||
showCancel: true,
|
||||
dismissible: dismissible,
|
||||
onConfirm: () => {
|
||||
onConfirm?.()
|
||||
setTimeout(() => {
|
||||
setDialogs((before) => before.filter((item) => item.id !== id))
|
||||
}, 300)
|
||||
},
|
||||
onCancel: () => {
|
||||
onCancel?.()
|
||||
setTimeout(() => {
|
||||
setDialogs((before) => before.filter((item) => item.id !== id))
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<DialogContext.Provider
|
||||
value={{
|
||||
alert,
|
||||
confirm
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
{dialogs?.map(({ id, ...props }) => <Modal key={id} {...props} />)}
|
||||
</DialogContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export default DialogProvider
|
||||
90
napcat.webui/src/contexts/songs.tsx
Normal file
90
napcat.webui/src/contexts/songs.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
// Songs Context
|
||||
import { useLocalStorage } from '@uidotdev/usehooks'
|
||||
import { createContext, useEffect, useState } from 'react'
|
||||
|
||||
import { PlayMode } from '@/const/enum'
|
||||
import key from '@/const/key'
|
||||
|
||||
import AudioPlayer from '@/components/audio_player'
|
||||
|
||||
import { get163MusicListSongs, getNextMusic } from '@/utils/music'
|
||||
|
||||
import type { FinalMusic } from '@/types/music'
|
||||
|
||||
export interface MusicContextProps {
|
||||
setListId: (id: string) => void
|
||||
listId: string
|
||||
onNext: () => void
|
||||
onPrevious: () => void
|
||||
}
|
||||
|
||||
export interface MusicProviderProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export const AudioContext = createContext<MusicContextProps>({
|
||||
setListId: () => {},
|
||||
listId: '5438670983',
|
||||
onNext: () => {},
|
||||
onPrevious: () => {}
|
||||
})
|
||||
|
||||
const AudioProvider: React.FC<MusicProviderProps> = ({ children }) => {
|
||||
const [listId, setListId] = useLocalStorage(key.musicID, '5438670983')
|
||||
const [musicList, setMusicList] = useState<FinalMusic[]>([])
|
||||
const [musicId, setMusicId] = useState<number>(0)
|
||||
const [playMode, setPlayMode] = useState<PlayMode>(PlayMode.Loop)
|
||||
const music = musicList.find((music) => music.id === musicId)
|
||||
const onNext = () => {
|
||||
const nextID = getNextMusic(musicList, musicId, playMode)
|
||||
setMusicId(nextID)
|
||||
}
|
||||
const onPrevious = () => {
|
||||
const index = musicList.findIndex((music) => music.id === musicId)
|
||||
if (index === 0) {
|
||||
setMusicId(musicList[musicList.length - 1].id)
|
||||
} else {
|
||||
setMusicId(musicList[index - 1].id)
|
||||
}
|
||||
}
|
||||
const onPlayEnd = () => {
|
||||
const nextID = getNextMusic(musicList, musicId, playMode)
|
||||
setMusicId(nextID)
|
||||
}
|
||||
const changeMode = (mode: PlayMode) => {
|
||||
setPlayMode(mode)
|
||||
}
|
||||
const fetchMusicList = async (id: string) => {
|
||||
const res = await get163MusicListSongs(id)
|
||||
setMusicList(res)
|
||||
setMusicId(res[0].id)
|
||||
}
|
||||
useEffect(() => {
|
||||
fetchMusicList(listId)
|
||||
}, [listId])
|
||||
return (
|
||||
<AudioContext.Provider
|
||||
value={{
|
||||
setListId,
|
||||
listId,
|
||||
onNext,
|
||||
onPrevious
|
||||
}}
|
||||
>
|
||||
<AudioPlayer
|
||||
title={music?.title}
|
||||
src={music?.url || ''}
|
||||
artist={music?.artist}
|
||||
cover={music?.cover}
|
||||
mode={playMode}
|
||||
pressNext={onNext}
|
||||
pressPrevious={onPrevious}
|
||||
onPlayEnd={onPlayEnd}
|
||||
onChangeMode={changeMode}
|
||||
/>
|
||||
{children}
|
||||
</AudioContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export default AudioProvider
|
||||
Reference in New Issue
Block a user