@@ -9,6 +9,7 @@ import { useArtists } from './hooks/useArtists';
99import { useFileUpload } from './hooks/useFileUpload' ;
1010import { useNetease } from './hooks/useNetease' ;
1111import { usePageTitle } from './hooks/usePageTitle' ;
12+ import { useSharePanel } from './hooks/useSharePanel' ;
1213import { getFontFamily } from './utils/fontUtils' ;
1314import { ErrorService } from './utils/errorService' ;
1415import ErrorBoundary from './components/ErrorBoundary' ;
@@ -19,13 +20,14 @@ import GlobalBackground from './components/GlobalBackground';
1920import MiniPlayerBar from './components/MiniPlayerBar' ;
2021import { getSongDetail , getSongUrl , getSongLyric , getAlbumCoverUrl } from './apis/netease' ;
2122
22- type NavTab = 'songs' | 'artists' | 'netease' | 'together' | 'settings' ;
23+ type NavTab = 'songs' | 'artists' | 'netease' | 'together' | 'settings' | 'share' ;
2324
2425const ArtistsView = lazy ( ( ) => import ( './components/ArtistsView' ) . then ( m => ( { default : m . ArtistsView } ) ) ) ;
2526const NeteasePanel = lazy ( ( ) => import ( './components/NeteasePanel' ) . then ( m => ( { default : m . NeteasePanel } ) ) ) ;
2627const SettingsPanel = lazy ( ( ) => import ( './components/SettingsPanel' ) ) ;
2728const MusicPlayer = lazy ( ( ) => import ( './components/MusicPlayer' ) ) ;
2829const TogetherListenPanel = lazy ( ( ) => import ( './components/TogetherListenPanel' ) ) ;
30+ const SharePanel = lazy ( ( ) => import ( './components/SharePanel' ) ) ;
2931
3032const LoadingFallback = ( ) => (
3133 < div className = "flex items-center justify-center h-full" >
@@ -61,6 +63,8 @@ const AppContent: React.FC = () => {
6163 activeTab
6264 } ) ;
6365
66+ const sharePanel = useSharePanel ( ) ;
67+
6468 const loadMusicFromUrl = useCallback ( async ( item : PlaylistItem , index : number ) => {
6569 setErrorMessage ( null ) ;
6670 playlist . setCurrentIndex ( index ) ;
@@ -72,6 +76,7 @@ const AppContent: React.FC = () => {
7276 album : item . album ,
7377 coverUrl : item . coverUrl ,
7478 lyrics : item . lyrics ,
79+ translatedLyrics : item . translatedLyrics ,
7580 neteaseId : item . neteaseId ,
7681 artistIds : item . artistIds ,
7782 file : item . file
@@ -279,18 +284,11 @@ const AppContent: React.FC = () => {
279284 const audio = player . audioRef . current ;
280285 if ( ! audio ) return ;
281286
282- const handleEnded = ( ) => {
283- console . log ( '===== Ended event triggered =====' ) ;
284- console . log ( 'Current playback mode:' , player . playbackMode ) ;
285- console . log ( 'Current track:' , player . track ?. metadata . title ) ;
286- console . log ( 'Is playing netease:' , ! ! player . track ?. neteaseId ) ;
287-
287+ const handleEnded = ( ) => {
288288 if ( player . playbackMode === 'single' ) {
289- console . log ( 'Single mode: restarting current track' ) ;
290289 audio . currentTime = 0 ;
291290 audio . play ( ) . catch ( ( ) => { } ) ;
292291 } else {
293- console . log ( 'List/shuffle mode: calling handleNext' ) ;
294292 handleNext ( ) ;
295293 }
296294 } ;
@@ -310,6 +308,26 @@ const AppContent: React.FC = () => {
310308 } , 300 ) ;
311309 } , [ ] ) ;
312310
311+ const handleShareClick = useCallback ( ( ) => {
312+ if ( ! player . track ) return ;
313+
314+ if ( player . track . neteaseId ) {
315+ sharePanel . updateConfig ( 'enableNeteaseMusicId' , true ) ;
316+ sharePanel . updateConfig ( 'neteaseMusicId' , player . track . neteaseId . toString ( ) ) ;
317+ sharePanel . updateConfig ( 'enableTrackIndex' , false ) ;
318+ sharePanel . updateConfig ( 'playlistOrigin' , '' ) ;
319+ } else {
320+ sharePanel . updateConfig ( 'enableTrackIndex' , true ) ;
321+ sharePanel . updateConfig ( 'trackIndex' , playlist . currentIndex . toString ( ) ) ;
322+ sharePanel . updateConfig ( 'enableNeteaseMusicId' , false ) ;
323+ sharePanel . updateConfig ( 'playlistOrigin' , settings . customSourceUrl || defaultSourceUrl ) ;
324+ }
325+
326+ sharePanel . updateConfig ( 'seekTo' , '' ) ;
327+ setShowFullPlayer ( false ) ;
328+ setActiveTab ( 'share' ) ;
329+ } , [ player . track , playlist . currentIndex , sharePanel , settings . customSourceUrl ] ) ;
330+
313331 const handleSeek = useCallback ( ( time : number ) => {
314332 if ( player . audioRef . current && time >= 0 ) {
315333 player . audioRef . current . currentTime = time ;
@@ -397,6 +415,34 @@ const AppContent: React.FC = () => {
397415 </ div >
398416 </ Suspense >
399417 ) ;
418+ case 'share' :
419+ return (
420+ < Suspense fallback = { < LoadingFallback /> } >
421+ < div className = "h-full flex flex-col" >
422+ < div className = "p-6 border-b border-white/[0.05]" >
423+ < h2 className = "text-2xl font-bold text-white drop-shadow-md" > 分享</ h2 >
424+ < p className = "text-sm text-white/40 mt-1 drop-shadow-sm" > 生成分享链接</ p >
425+ </ div >
426+ < div className = "flex-1 overflow-y-auto playlist-scrollbar p-4" >
427+ < SharePanel
428+ isOpen = { true }
429+ onClose = { ( ) => { } }
430+ config = { sharePanel . config }
431+ updateConfig = { sharePanel . updateConfig }
432+ shareUrl = { sharePanel . shareUrl }
433+ resetConfig = { sharePanel . resetConfig }
434+ onReadCurrentTime = { ( ) => sharePanel . readCurrentTime ( player . currentTime ) }
435+ onReadCurrentUrl = { ( ) => sharePanel . readCurrentUrl ( settings . customSourceUrl || defaultSourceUrl ) }
436+ onReadCurrentTrack = { handleShareClick }
437+ onCopy = { sharePanel . copyToClipboard }
438+ onValidate = { sharePanel . validateConfig }
439+ currentTime = { player . currentTime }
440+ isMobile = { false }
441+ />
442+ </ div >
443+ </ div >
444+ </ Suspense >
445+ ) ;
400446 case 'songs' :
401447 default :
402448 return (
@@ -419,7 +465,7 @@ const AppContent: React.FC = () => {
419465 />
420466 ) ;
421467 }
422- } , [ activeTab , selectedArtist , playlist , player , settings , artistsByLetter , pinyinLoadError , loadMusicFromUrl , loadNeteaseMusic , triggerFileUpload , triggerFolderUpload ] ) ;
468+ } , [ activeTab , selectedArtist , playlist , player , settings , artistsByLetter , pinyinLoadError , loadMusicFromUrl , loadNeteaseMusic , triggerFileUpload , triggerFolderUpload , sharePanel ] ) ;
423469
424470 return (
425471 < div className = "h-screen w-full overflow-hidden" style = { { fontFamily : getFontFamily ( settings . selectedFont ) } } >
@@ -558,6 +604,7 @@ const AppContent: React.FC = () => {
558604 formatTime = { player . formatTime }
559605 onArtistClick = { handleArtistClick }
560606 isTogetherListenConnected = { isTogetherListenConnected }
607+ onShareClick = { handleShareClick }
561608 />
562609 </ Suspense >
563610 </ div >
0 commit comments