app.tsx 2.0 KB

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