diff --git a/src/components/generic-components.ts b/src/components/generic-components.ts index afd3853e..bab5aa38 100644 --- a/src/components/generic-components.ts +++ b/src/components/generic-components.ts @@ -2,4 +2,10 @@ import styled from "@emotion/styled"; export const FlexContainer = styled.div` display: flex; + flex-wrap: wrap; +`; + +export const DisplayContainer = styled.div` + display: flex; + padding: 2rem; `; diff --git a/src/components/landing-page/landing-page.tsx b/src/components/landing-page/landing-page.tsx index 4908c17a..2498aa64 100644 --- a/src/components/landing-page/landing-page.tsx +++ b/src/components/landing-page/landing-page.tsx @@ -1,24 +1,10 @@ -import styled from "@emotion/styled"; import { JoinProduction } from "./join-production.tsx"; import { CreateProduction } from "./create-production.tsx"; import { ProductionsList } from "./productions-list.tsx"; import { useNavigateToProduction } from "./use-navigate-to-production.ts"; -import { FlexContainer } from "../generic-components.ts"; +import { DisplayContainer, FlexContainer } from "../generic-components.ts"; import { useGlobalState } from "../../global-state/context-provider.tsx"; - -const DisplayContainer = styled.div` - flex-basis: 100%; - display: flex; - - &:first-of-type { - border-right: 1px solid #424242; - padding: 5rem 2rem 5rem 5rem; - justify-content: flex-end; - } - &:last-of-type { - padding: 5rem 5rem 5rem 2rem; - } -`; +import { isMobile } from "../../bowser.ts"; export const LandingPage = () => { const [{ joinProductionOptions }] = useGlobalState(); @@ -31,9 +17,11 @@ export const LandingPage = () => { - - - + {!isMobile && ( + + + + )} diff --git a/src/components/landing-page/productions-list.tsx b/src/components/landing-page/productions-list.tsx index 03c4d7fa..3ca85f1f 100644 --- a/src/components/landing-page/productions-list.tsx +++ b/src/components/landing-page/productions-list.tsx @@ -5,6 +5,8 @@ import { TBasicProduction } from "../production-line/types.ts"; import { useGlobalState } from "../../global-state/context-provider.tsx"; import { LoaderDots } from "../loader/loader.tsx"; import { useRefreshAnimation } from "./use-refresh-animation.ts"; +import { DisplayContainerHeader } from "./display-container-header.tsx"; +import { DisplayContainer } from "../generic-components.ts"; const ProductionListContainer = styled.div` display: flex; @@ -54,13 +56,6 @@ export const ProductionsList = () => { .slice(-10) // display in reverse order .toReversed() - // convert to local format - .map((prod) => { - return { - name: prod.name, - id: parseInt(prod.productionid, 10), - }; - }) ); dispatch({ @@ -99,11 +94,14 @@ export const ProductionsList = () => { return ( <> + + Production List + {productions.map((p) => ( - + {p.name} - {p.id} + {p.productionid} ))} diff --git a/src/components/landing-page/use-fetch-production.ts b/src/components/landing-page/use-fetch-production.ts index 1d33f7cb..3cfb55b0 100644 --- a/src/components/landing-page/use-fetch-production.ts +++ b/src/components/landing-page/use-fetch-production.ts @@ -21,16 +21,7 @@ export const useFetchProduction: TUseFetchProduction = (id) => { setError(null); - setProduction({ - name: p.name, - id: parseInt(p.productionid, 10), - lines: p.lines.map((line) => ({ - name: line.name, - id: parseInt(line.id, 10), - participants: [], - connected: false, - })), - }); + setProduction(p); }) .catch((e) => { setProduction(null); diff --git a/src/components/production-line/production-line.tsx b/src/components/production-line/production-line.tsx index 6ea0672d..8ec7ca4b 100644 --- a/src/components/production-line/production-line.tsx +++ b/src/components/production-line/production-line.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import { FC, useEffect, useRef, useState } from "react"; +import { FC, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useGlobalState } from "../../global-state/context-provider.tsx"; import { useAudioInput } from "./use-audio-input.ts"; @@ -11,9 +11,26 @@ import { API } from "../../api/api.ts"; import { noop } from "../../helpers.ts"; import { MicMuted, MicUnmuted } from "../../assets/icons/icon.tsx"; import { Spinner } from "../loader/loader.tsx"; +import { TLine, TProduction } from "./types.ts"; +import { DisplayContainerHeader } from "../landing-page/display-container-header.tsx"; +import { DisplayContainer, FlexContainer } from "../generic-components.ts"; const TempDiv = styled.div` - padding: 1rem; + padding: 1rem 0; +`; + +const HeaderWrapper = styled.div` + padding: 2rem; + display: flex; + flex-wrap: wrap; +`; + +const SmallText = styled.span` + font-size: 1.6rem; +`; + +const ButtonWrapper = styled.span` + margin: 0 2rem 0 0; `; const UserControlBtn = styled.button` @@ -26,12 +43,11 @@ export const ProductionLine: FC = () => { const [{ joinProductionOptions, mediaStreamInput }, dispatch] = useGlobalState(); const navigate = useNavigate(); - const audioContainerRef = useRef(null); const [micMute, setMicMute] = useState(true); - const [participants, setParticipants] = useState< - { name: string; sessionid: string }[] | null - >(null); + const [line, setLine] = useState(null); + const [loading, setLoading] = useState(true); + const [production, setProduction] = useState(null); const inputAudioStream = useAudioInput({ inputId: joinProductionOptions?.audioinput ?? null, @@ -57,7 +73,7 @@ export const ProductionLine: FC = () => { const interval = window.setInterval(() => { API.fetchProductionLine(productionId, lineId) - .then((line) => setParticipants(line.participants)) + .then((l) => setLine(l)) .catch(console.error); }, 1000); @@ -66,6 +82,16 @@ export const ProductionLine: FC = () => { }; }, [joinProductionOptions]); + useEffect(() => { + if (!joinProductionOptions) return; + + const productionId = parseInt(joinProductionOptions.productionId, 10); + + API.fetchProduction(productionId).then((p) => { + setProduction(p); + }); + }, [joinProductionOptions]); + // TODO temporary, this view should handle direct links useEffect(() => { if (!joinProductionOptions) { @@ -101,34 +127,54 @@ export const ProductionLine: FC = () => { // Mute/Unmute speaker // Show active sink and mic - // Exit button (link to /, clear production from state) return ( -
- - Exit - + <> + + + Exit + + {!loading && production && line && ( + + Production: {production.name}{" "} + Line: {line.name} + + )} + + {loading && } + {!loading && ( - <> - Production View - - setMicMute(!micMute)}> - {micMute ? : } - - - - {audioElements.length && ( - Incoming Audio Channels: {audioElements.length} - )} - {connectionState && ( - RTC Connection State: {connectionState} - )} - - - + + +
+ Controls + + {audioElements.length && ( + + Incoming Audio Channels: {audioElements.length} + + )} + {connectionState && ( + RTC Connection State: {connectionState} + )} + + + setMicMute(!micMute)} + > + {micMute ? : } + + +
+
+ + {line && } + +
)} -
+ ); }; diff --git a/src/components/production-line/types.ts b/src/components/production-line/types.ts index ddbde4a2..5493d2ff 100644 --- a/src/components/production-line/types.ts +++ b/src/components/production-line/types.ts @@ -10,19 +10,19 @@ export type TJoinProductionOptions = { export type TParticipant = { name: string; - active: boolean; + sessionid: string; + isActive: boolean; }; export type TLine = { name: string; - id: number; - connected: boolean; + id: string; participants: TParticipant[]; }; export type TBasicProduction = { name: string; - id: number; + productionid: string; }; export type TProduction = TBasicProduction & { diff --git a/src/components/production-line/user-list.tsx b/src/components/production-line/user-list.tsx index 36a00e22..fb5c77ec 100644 --- a/src/components/production-line/user-list.tsx +++ b/src/components/production-line/user-list.tsx @@ -1,5 +1,6 @@ import styled from "@emotion/styled"; import { DisplayContainerHeader } from "../landing-page/display-container-header.tsx"; +import { TParticipant } from "./types.ts"; const ListWrapper = styled.div` padding: 1rem; @@ -12,7 +13,6 @@ const User = styled.div` color: #ddd; max-width: 32rem; display: flex; - align-items: center; `; const GreenCircle = styled.div` @@ -25,7 +25,7 @@ const GreenCircle = styled.div` `; type TUserListOptions = { - participants: { name: string; sessionid: string }[] | null; + participants: TParticipant[]; }; export const UserList = ({ participants }: TUserListOptions) => { if (!participants) return null;