app.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import React, { Dispatch, Suspense, useCallback } from 'react';
  2. import { StateInspector } from 'reinspect';
  3. import { LocalAction, stateSet } from '../actions';
  4. import { DispatchContext, StateContext } from '../context/state';
  5. import { useMaster } from '../hooks/master';
  6. import { useKeepalive } from '../hooks/socket';
  7. import { useCurrentlyPlayingSongInfo } from '../hooks/status';
  8. import { GlobalState } from '../reducer';
  9. import { isMaster } from '../selectors';
  10. import { getSongUrl } from '../utils/url';
  11. import { LoadingWrapper } from './identify';
  12. import { Player } from './player';
  13. import { uiProviders } from './ui';
  14. import { UIProvider } from './ui/types';
  15. export type Props = {
  16. socket: WebSocket;
  17. state: GlobalState;
  18. dispatch: Dispatch<LocalAction>;
  19. };
  20. const uiProvider = UIProvider.Cmus;
  21. const UI = uiProviders[uiProvider];
  22. export const App: React.FC<Props> = ({ socket, state, dispatch }) => {
  23. useKeepalive(socket);
  24. useMaster(state, dispatch);
  25. const currentSong = useCurrentlyPlayingSongInfo(state.player.songId);
  26. const onTimeUpdate = useCallback(
  27. (currentTime: number): void => {
  28. dispatch(stateSet({ currentTime }));
  29. },
  30. [dispatch],
  31. );
  32. return (
  33. <>
  34. {isMaster(state) && !!state.player.songId && (
  35. <Player
  36. src={getSongUrl(state.player.songId)}
  37. playing={state.player.playing}
  38. seekTime={state.player.seekTime}
  39. onTimeUpdate={onTimeUpdate}
  40. timeUpdateFPS={1}
  41. />
  42. )}
  43. <StateContext.Provider value={state}>
  44. <DispatchContext.Provider value={dispatch}>
  45. <StateInspector name="ui">
  46. <Suspense fallback={<LoadingWrapper />}>
  47. <UI isMaster={isMaster(state)} currentSong={currentSong} />
  48. </Suspense>
  49. </StateInspector>
  50. </DispatchContext.Provider>
  51. </StateContext.Provider>
  52. </>
  53. );
  54. };