Просмотр исходного кода

feat: separate client list icon for active vs master

Fela Maslen 4 лет назад
Родитель
Сommit
fd77cb9c1f
2 измененных файлов с 26 добавлено и 12 удалено
  1. 5 1
      gmus-backend/pkg/server/types.go
  2. 21 11
      gmus-web/src/components/ui/cmus/views/clients.tsx

+ 5 - 1
gmus-backend/pkg/server/types.go

@@ -26,7 +26,11 @@ type Member struct {
 // an action across first should cause the other to obey the instruction
 // and treat the first as master.
 //
-// The master client is responsible for keeping the server updated regularly about the current state
+// The master client is responsible for keeping the server updated regularly about the current state.
+//
+// Active clients are all those clients which are responsible for playing the song.
+// In contrast to master, there can be more than one active client.
+// The master client is automatically active.
 //
 // This type here is merely used for validation of client state messages.
 // Each client implementation MUST adhere to this spec.

+ 21 - 11
gmus-web/src/components/ui/cmus/views/clients.tsx

@@ -12,16 +12,25 @@ import * as Styled from './clients.styles';
 
 type ClientRowProps = {
   name: string;
-  active: boolean;
+  selected: boolean;
   isMe: boolean;
   isMaster: boolean;
+  isActive: boolean;
   isPaused: boolean;
 };
 
-const ClientRow: React.FC<ClientRowProps> = ({ name, active, isMe, isMaster, isPaused }) => (
-  <Styled.Client highlight={isMaster} active={active} parentActive={true}>
+const ClientRow: React.FC<ClientRowProps> = ({
+  name,
+  selected,
+  isMe,
+  isMaster,
+  isActive,
+  isPaused,
+}) => (
+  <Styled.Client highlight={isMaster} active={selected} parentActive={true}>
     <Styled.ClientName>{name}</Styled.ClientName>
-    {isMaster && (isPaused ? '🔈' : '🔊')}
+    {isMaster && '🤠'}
+    {(isActive || isMaster) && (isPaused ? '🔈' : '🔊')}
     {isMe ? '🏠' : '📶'}
   </Styled.Client>
 );
@@ -30,13 +39,13 @@ export const ViewClientList: React.FC = () => {
   const {
     clientList,
     myClientName,
-    player: { master, playing },
+    player: { master, activeClients, playing },
   } = useContext(StateContext);
 
   const dispatchUI = useContext(CmusUIDispatchContext);
   const {
     scroll,
-    clientList: { active: activeClient },
+    clientList: { active: selectedClient },
   } = useContext(CmusUIStateContext);
 
   const ref = useRef<HTMLDivElement>(null);
@@ -46,14 +55,14 @@ export const ViewClientList: React.FC = () => {
     [clientList],
   );
 
-  const setActiveClient = useCallback((name: string) => dispatchUI(clientActivated(name)), [
+  const setselectedClient = useCallback((name: string) => dispatchUI(clientActivated(name)), [
     dispatchUI,
   ]);
 
   const onScroll = useCallback(
     (delta: -1 | 1): void => {
-      setActiveClient(
-        scrollThroughItems(sortedClientList, (compare) => compare.name === activeClient, delta)
+      setselectedClient(
+        scrollThroughItems(sortedClientList, (compare) => compare.name === selectedClient, delta)
           .name,
       );
 
@@ -61,7 +70,7 @@ export const ViewClientList: React.FC = () => {
         ref.current.scrollTop += delta * lineHeight;
       }
     },
-    [sortedClientList, activeClient, setActiveClient],
+    [sortedClientList, selectedClient, setselectedClient],
   );
 
   const lastScrollSerial = useRef<number>(0);
@@ -80,9 +89,10 @@ export const ViewClientList: React.FC = () => {
           <ClientRow
             key={name}
             name={name}
-            active={name === activeClient}
+            selected={name === selectedClient}
             isMe={name === myClientName}
             isMaster={name === master}
+            isActive={activeClients.includes(name)}
             isPaused={!playing}
           />
         ))}