Explorar el Código

feat: separate component for mobile UI

Fela Maslen hace 5 años
padre
commit
b8fdf0cf3f

+ 2 - 0
gmus-web/package.json

@@ -65,6 +65,7 @@
     "@types/pluralize": "^0.0.29",
     "@types/react": "^16.9.53",
     "@types/react-dom": "^16.9.8",
+    "@types/react-responsive": "^8.0.2",
     "@types/react-virtualized-auto-sizer": "^1.0.0",
     "@types/react-window": "^1.8.2",
     "@types/styled-components": "^5.1.5",
@@ -83,6 +84,7 @@
     "prettier": "^2.2.1",
     "react": "^17.0.1",
     "react-dom": "^17.0.1",
+    "react-responsive": "^8.2.0",
     "react-scripts": "4.0.1",
     "react-spinners": "^0.9.0",
     "react-storage-hooks": "^4.0.1",

+ 8 - 6
gmus-web/src/components/app.tsx

@@ -1,9 +1,9 @@
-import React, { Suspense, useCallback, useContext } from 'react';
+import React, { Suspense, useCallback, useContext, useMemo } from 'react';
+import { useMediaQuery } from 'react-responsive';
 import { StateInspector } from 'reinspect';
 
 import { stateSet } from '../actions';
 import { DispatchContext, StateContext } from '../context/state';
-import { useMaster } from '../hooks/master';
 import { usePlayQueue } from '../hooks/queue';
 import { useKeepalive } from '../hooks/socket';
 import { useCurrentlyPlayingSongInfo } from '../hooks/status';
@@ -20,12 +20,8 @@ export type Props = {
   interacted: boolean;
 } & InteractProps;
 
-const uiProvider = UIProvider.Cmus;
-const UI = uiProviders[uiProvider];
-
 export const App: React.FC<Props> = ({ socket, interacted, setInteracted }) => {
   useKeepalive(socket);
-  useMaster();
   useCurrentlyPlayingSongInfo();
 
   const state = useContext(StateContext);
@@ -40,6 +36,12 @@ export const App: React.FC<Props> = ({ socket, interacted, setInteracted }) => {
 
   const { onNext, onPrev } = usePlayQueue();
 
+  const isDesktop = useMediaQuery({ query: '(min-device-width: 1280px)' });
+
+  const UI = useMemo(() => uiProviders[isDesktop ? UIProvider.Cmus : UIProvider.Mobile], [
+    isDesktop,
+  ]);
+
   return (
     <>
       {isMaster(state) && !!state.player.songId && (

+ 3 - 0
gmus-web/src/components/ui/cmus/wrapper.tsx

@@ -2,6 +2,7 @@ import React, { useContext, useEffect, useRef } from 'react';
 import { useReducer } from 'reinspect';
 
 import { DispatchContext } from '../../../context/state';
+import { useMaster } from '../../../hooks/master';
 import { useVimBindings } from '../../../hooks/vim';
 import { init } from '../../../utils/state';
 
@@ -28,6 +29,8 @@ import * as Styled from './wrapper.styles';
 const viewTitles = Object.values(View);
 
 export const CmusUIProvider: UIProviderComponent = ({ currentSong, nextSong, prevSong }) => {
+  useMaster();
+
   const dispatch = useContext(DispatchContext);
   const [stateUI, dispatchUI] = useReducer(cmusUIReducer, initialCmusUIState, init, 'ui');
 

+ 1 - 0
gmus-web/src/components/ui/index.ts

@@ -3,4 +3,5 @@ import { UIProvider, UIProviders } from './types';
 
 export const uiProviders: UIProviders = {
   [UIProvider.Cmus]: lazy(() => import('./cmus')),
+  [UIProvider.Mobile]: lazy(() => import('./mobile')),
 };

+ 3 - 0
gmus-web/src/components/ui/mobile/index.ts

@@ -0,0 +1,3 @@
+import { MobileUIProvider } from './wrapper';
+
+export default MobileUIProvider;

+ 4 - 0
gmus-web/src/components/ui/mobile/wrapper.tsx

@@ -0,0 +1,4 @@
+import React from 'react';
+import { UIProviderComponent } from '../types';
+
+export const MobileUIProvider: UIProviderComponent = () => <span>Mobile UI innit</span>;

+ 1 - 0
gmus-web/src/components/ui/types.ts

@@ -4,6 +4,7 @@ import { Song } from '../../types';
 
 export enum UIProvider {
   Cmus = 'Cmus',
+  Mobile = 'Mobile',
 }
 
 export type UIProps = {

+ 40 - 1
gmus-web/yarn.lock

@@ -1964,6 +1964,13 @@
   dependencies:
     "@types/react" "*"
 
+"@types/react-responsive@^8.0.2":
+  version "8.0.2"
+  resolved "https://registry.yarnpkg.com/@types/react-responsive/-/react-responsive-8.0.2.tgz#959fdc32f72e38b807e32be617a74be2c315081b"
+  integrity sha512-DTvm3Hb77v0hme7L4GYzRjLQqlZP+zNImFBzdKbSH7CsQ5c7QebGnSQX2Xf3BaA0rm/TQE57eFMhMGLcMe/A9w==
+  dependencies:
+    "@types/react" "*"
+
 "@types/react-virtualized-auto-sizer@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.0.tgz#fc32f30a8dab527b5816f3a757e1e1d040c8f272"
@@ -3940,6 +3947,11 @@ css-loader@4.3.0:
     schema-utils "^2.7.1"
     semver "^7.3.2"
 
+css-mediaquery@^0.1.2:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0"
+  integrity sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=
+
 css-prefers-color-scheme@^3.1.1:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4"
@@ -5972,6 +5984,11 @@ husky@^4.3.6:
     slash "^3.0.0"
     which-pm-runs "^1.0.0"
 
+hyphenate-style-name@^1.0.0:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
+  integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
+
 iconv-lite@0.4.24:
   version "0.4.24"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -7439,6 +7456,13 @@ map-visit@^1.0.0:
   dependencies:
     object-visit "^1.0.0"
 
+matchmediaquery@^0.3.0:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/matchmediaquery/-/matchmediaquery-0.3.1.tgz#8247edc47e499ebb7c58f62a9ff9ccf5b815c6d7"
+  integrity sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==
+  dependencies:
+    css-mediaquery "^0.1.2"
+
 md5.js@^1.3.4:
   version "1.3.5"
   resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -9240,7 +9264,7 @@ prompts@2.4.0, prompts@^2.0.1:
     kleur "^3.0.3"
     sisteransi "^1.0.5"
 
-prop-types@^15.7.2:
+prop-types@^15.6.1, prop-types@^15.7.2:
   version "15.7.2"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
   integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -9470,6 +9494,16 @@ react-refresh@^0.8.3:
   resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
   integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
 
+react-responsive@^8.2.0:
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/react-responsive/-/react-responsive-8.2.0.tgz#e0ffb306cfd8f38c9c12e26725b9e1245fa9debc"
+  integrity sha512-iagCqVrw4QSjhxKp3I/YK6+ODkWY6G+YPElvdYKiUUbywwh9Ds0M7r26Fj2/7dWFFbOpcGnJE6uE7aMck8j5Qg==
+  dependencies:
+    hyphenate-style-name "^1.0.0"
+    matchmediaquery "^0.3.0"
+    prop-types "^15.6.1"
+    shallow-equal "^1.1.0"
+
 react-scripts@4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.1.tgz#34974c0f4cfdf1655906c95df6a04d80db8b88f0"
@@ -10288,6 +10322,11 @@ shallow-clone@^3.0.0:
   dependencies:
     kind-of "^6.0.2"
 
+shallow-equal@^1.1.0:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
+  integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
+
 shallowequal@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"