diff --git a/packages/napcat-webui-frontend/src/App.tsx b/packages/napcat-webui-frontend/src/App.tsx index 37a8f124..e21a60ca 100644 --- a/packages/napcat-webui-frontend/src/App.tsx +++ b/packages/napcat-webui-frontend/src/App.tsx @@ -7,7 +7,6 @@ import PageLoading from '@/components/page_loading'; import Toaster from '@/components/toaster'; import DialogProvider from '@/contexts/dialog'; -import AudioProvider from '@/contexts/songs'; import useAuth from '@/hooks/auth'; @@ -33,13 +32,11 @@ function App () { - - }> - - - - - + }> + + + + ); diff --git a/packages/napcat-webui-frontend/src/components/audio_player.tsx b/packages/napcat-webui-frontend/src/components/audio_player.tsx deleted file mode 100644 index b77f4d6b..00000000 --- a/packages/napcat-webui-frontend/src/components/audio_player.tsx +++ /dev/null @@ -1,425 +0,0 @@ -import { Button } from '@heroui/button'; -import { Card, CardBody, CardHeader } from '@heroui/card'; -import { Image } from '@heroui/image'; -import { Popover, PopoverContent, PopoverTrigger } from '@heroui/popover'; -import { Slider } from '@heroui/slider'; -import { Tooltip } from '@heroui/tooltip'; -import { useLocalStorage } from '@uidotdev/usehooks'; -import clsx from 'clsx'; -import { useEffect, useRef, useState } from 'react'; -import { - BiSolidSkipNextCircle, - BiSolidSkipPreviousCircle, -} from 'react-icons/bi'; -import { - FaPause, - FaPlay, - FaRegHandPointRight, - FaRepeat, - FaShuffle, -} from 'react-icons/fa6'; -import { TbRepeatOnce } from 'react-icons/tb'; -import { useMediaQuery } from 'react-responsive'; - -import { PlayMode } from '@/const/enum'; -import key from '@/const/key'; - -import { VolumeHighIcon, VolumeLowIcon } from './icons'; - -export interface AudioPlayerProps - extends React.AudioHTMLAttributes { - src: string - title?: string - artist?: string - cover?: string - pressNext?: () => void - pressPrevious?: () => void - onPlayEnd?: () => void - onChangeMode?: (mode: PlayMode) => void - mode?: PlayMode -} - -export default function AudioPlayer (props: AudioPlayerProps) { - const { - src, - pressNext, - pressPrevious, - cover = 'https://nextui.org/images/album-cover.png', - title = '未知', - artist = '未知', - onTimeUpdate, - onLoadedData, - onPlay, - onPause, - onPlayEnd, - onChangeMode, - autoPlay, - mode = PlayMode.Loop, - ...rest - } = props; - - const [currentTime, setCurrentTime] = useState(0); - const [duration, setDuration] = useState(0); - const [isPlaying, setIsPlaying] = useState(false); - const [volume, setVolume] = useState(100); - const [isCollapsed, setIsCollapsed] = useLocalStorage( - key.isCollapsedMusicPlayer, - false - ); - const audioRef = useRef(null); - const cardRef = useRef(null); - const startY = useRef(0); - const startX = useRef(0); - const [translateY, setTranslateY] = useState(0); - const [translateX, setTranslateX] = useState(0); - const isSmallScreen = useMediaQuery({ maxWidth: 767 }); - const isMediumUp = useMediaQuery({ minWidth: 768 }); - const shouldAdd = useRef(false); - const currentProgress = (currentTime / duration) * 100; - const [storageAutoPlay, setStorageAutoPlay] = useLocalStorage( - key.autoPlay, - true - ); - - const handleTimeUpdate = (event: React.SyntheticEvent) => { - const audio = event.target as HTMLAudioElement; - setCurrentTime(audio.currentTime); - onTimeUpdate?.(event); - }; - - const handleLoadedData = (event: React.SyntheticEvent) => { - const audio = event.target as HTMLAudioElement; - setDuration(audio.duration); - onLoadedData?.(event); - }; - - const handlePlay = (e: React.SyntheticEvent) => { - setIsPlaying(true); - setStorageAutoPlay(true); - onPlay?.(e); - }; - - const handlePause = (e: React.SyntheticEvent) => { - setIsPlaying(false); - onPause?.(e); - }; - - const changeMode = () => { - const modes = [PlayMode.Loop, PlayMode.Random, PlayMode.Single]; - const currentIndex = modes.findIndex((_mode) => _mode === mode); - const nextIndex = currentIndex + 1; - const nextMode = modes[nextIndex] || modes[0]; - onChangeMode?.(nextMode); - }; - - const volumeChange = (value: number) => { - setVolume(value); - }; - - useEffect(() => { - const audio = audioRef.current; - if (audio) { - audio.volume = volume / 100; - } - }, [volume]); - - const handleTouchStart = (e: React.TouchEvent) => { - startY.current = e.touches[0].clientY; - startX.current = e.touches[0].clientX; - }; - - const handleTouchMove = (e: React.TouchEvent) => { - const deltaY = e.touches[0].clientY - startY.current; - const deltaX = e.touches[0].clientX - startX.current; - const container = cardRef.current; - const header = cardRef.current?.querySelector('[data-header]'); - const headerHeight = header?.clientHeight || 20; - const addHeight = (container?.clientHeight || headerHeight) - headerHeight; - const _shouldAdd = isCollapsed && deltaY < 0; - if (isSmallScreen) { - shouldAdd.current = _shouldAdd; - setTranslateY(_shouldAdd ? deltaY + addHeight : deltaY); - } else { - setTranslateX(deltaX); - } - }; - - const handleTouchEnd = () => { - if (isSmallScreen) { - const container = cardRef.current; - const header = cardRef.current?.querySelector('[data-header]'); - const headerHeight = header?.clientHeight || 20; - const addHeight = (container?.clientHeight || headerHeight) - headerHeight; - const _translateY = translateY - (shouldAdd.current ? addHeight : 0); - if (_translateY > 100) { - setIsCollapsed(true); - } else if (_translateY < -100) { - setIsCollapsed(false); - } - setTranslateY(0); - } else { - if (translateX > 100) { - setIsCollapsed(true); - } else if (translateX < -100) { - setIsCollapsed(false); - } - setTranslateX(0); - } - }; - - const dragTranslate = isSmallScreen - ? translateY - ? `translateY(${translateY}px)` - : '' - : translateX - ? `translateX(${translateX}px)` - : ''; - const collapsedTranslate = isCollapsed - ? isSmallScreen - ? 'translateY(90%)' - : 'translateX(96%)' - : ''; - - const translateStyle = dragTranslate || collapsedTranslate; - - if (!src) return null; - - return ( -
-