diff --git a/src/components/calls-page/calls-page.tsx b/src/components/calls-page/calls-page.tsx index ca1cd9f..910a910 100644 --- a/src/components/calls-page/calls-page.tsx +++ b/src/components/calls-page/calls-page.tsx @@ -3,15 +3,15 @@ import { useEffect, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { useGlobalState } from "../../global-state/context-provider"; import { JoinProduction } from "../landing-page/join-production"; -import { ProductionLine } from "../production-line/production-line"; import { PrimaryButton, SecondaryButton } from "../landing-page/form-elements"; import { NavigateToRootButton } from "../navigate-to-root-button/navigate-to-root-button"; import { DisplayContainerHeader } from "../landing-page/display-container-header"; import { Modal } from "../modal/modal"; import { VerifyDecision } from "../verify-decision/verify-decision"; import { ModalConfirmationText } from "../modal/modal-confirmation-text"; -import { MegaphoneIcon } from "../../assets/icons/icon"; +import { MicMuted, MicUnmuted } from "../../assets/icons/icon"; import { useGlobalHotkeys } from "../production-line/use-line-hotkeys"; +import { ProductionLine } from "../production-line/production-line"; const Container = styled.div` display: flex; @@ -24,7 +24,10 @@ const CallsContainer = styled.div` display: flex; flex-direction: row; flex-wrap: wrap; - padding: 2rem; + + form { + margin: 0; + } `; const CallContainer = styled.div` @@ -37,45 +40,38 @@ const CallContainer = styled.div` const AddCallContainer = styled.div` display: flex; - flex-direction: column; - padding: 4rem; - max-width: 40rem; - min-width: 30rem; `; const ButtonWrapper = styled.div` display: flex; - margin: 0 1rem 1rem 0; - :last-of-type { - margin: 0 0 4rem; - } + justify-content: space-between; + height: 4rem; `; const MuteAllCallsBtn = styled(PrimaryButton)` background: rgba(50, 56, 59, 1); color: #6fd84f; border: 0.2rem solid #6d6d6d; - padding: 0.5rem 1rem; - margin: 0 0 0 1rem; - width: fit-content; - height: 4rem; - &.mute { - color: #f96c6c; svg { fill: #f96c6c; } } + padding: 1rem; + margin-right: 1rem; + display: flex; + align-items: center; + color: white; + svg { fill: #6fd84f; width: 3rem; } `; -const MuteAllCallsBtnText = styled.span` - text-align: center; - width: 100%; +const HeaderRightSide = styled.div` + display: flex; `; export const CallsPage = () => { @@ -161,31 +157,52 @@ export const CallsPage = () => { } }} /> - {confirmExitModalOpen && ( - setConfirmExitModalOpen(false)}> - Confirm - - Are you sure you want to leave all calls? - - setConfirmExitModalOpen(false)} - /> - - )} - {!isEmpty && !isSingleCall && ( - setIsMasterInputMuted(!isMasterInputMuted)} - > - - {isMasterInputMuted ? "Mute" : "Unmute"} all Inputs - - - - )} + + {confirmExitModalOpen && ( + setConfirmExitModalOpen(false)}> + Confirm + + Are you sure you want to leave all calls? + + setConfirmExitModalOpen(false)} + /> + + )} + {!isEmpty && ( + setIsMasterInputMuted(!isMasterInputMuted)} + className={isMasterInputMuted ? "mute" : ""} + > + {isMasterInputMuted ? "Unmute All" : "Mute All"} + {isMasterInputMuted ? : } + + )} + {!isEmpty && ( + + + setAddCallActive(!addCallActive)} + > + Add Call + + + + )} + + {isEmpty && paramProductionId && paramLineId && ( + + )} {Object.entries(calls).map( ([callId, callState]) => @@ -203,32 +220,12 @@ export const CallsPage = () => { ) )} - {!isEmpty && ( - - - setAddCallActive(!addCallActive)} - > - Add Call - - - {addCallActive && productionId && ( - setAddCallActive(false)} - /> - )} - - )} - {isEmpty && paramProductionId && paramLineId && ( + {addCallActive && productionId && ( setAddCallActive(false)} + className="calls-page" /> )} diff --git a/src/components/landing-page/join-production.tsx b/src/components/landing-page/join-production.tsx index 6c0294b..2f1f27d 100644 --- a/src/components/landing-page/join-production.tsx +++ b/src/components/landing-page/join-production.tsx @@ -49,6 +49,7 @@ type TProps = { customGlobalMute: string; addAdditionalCallId?: string; closeAddCallView?: () => void; + className?: string; }; export const JoinProduction = ({ @@ -56,6 +57,7 @@ export const JoinProduction = ({ customGlobalMute, addAdditionalCallId, closeAddCallView, + className, }: TProps) => { const [joinProductionId, setJoinProductionId] = useState(null); const [joinProductionOptions, setJoinProductionOptions] = @@ -209,7 +211,9 @@ export const JoinProduction = ({ }; return ( - + Join Production {devices && ( <> diff --git a/src/components/production-line/collapsable-section.tsx b/src/components/production-line/collapsable-section.tsx new file mode 100644 index 0000000..ba361e3 --- /dev/null +++ b/src/components/production-line/collapsable-section.tsx @@ -0,0 +1,68 @@ +import styled from "@emotion/styled"; +import { FC, PropsWithChildren, useState } from "react"; +import { ChevronDownIcon, ChevronUpIcon } from "../../assets/icons/icon"; + +const SectionWrapper = styled.div` + border: 0.2rem #6d6d6d solid; + border-radius: 1rem; + padding: 1rem; + margin-bottom: 1rem; +`; + +const SectionHeader = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + height: 3rem; + font-weight: bold; + + &:hover { + cursor: pointer; + } +`; + +const SectionTitle = styled.div``; + +const SectionCollapser = styled.div` + width: 3rem; + height: 3rem; +`; + +const SectionBody = styled.div` + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 0.5s ease-out; + + &.open { + grid-template-rows: 1fr; + } +`; + +const SectionInner = styled.div` + overflow: hidden; +`; + +interface CollapsableSectionProps extends PropsWithChildren { + title: string; + startOpen?: boolean; +} + +export const CollapsableSection: FC = (props) => { + const { title, startOpen = false, children } = props; + + const [open, setOpen] = useState(startOpen); + + return ( + + setOpen(!open)}> + {title} + + {open ? : } + + + + {children} + + + ); +}; diff --git a/src/components/production-line/hotkeys-component.tsx b/src/components/production-line/hotkeys-component.tsx index d7a9012..c083794 100644 --- a/src/components/production-line/hotkeys-component.tsx +++ b/src/components/production-line/hotkeys-component.tsx @@ -9,16 +9,17 @@ const TempDiv = styled.div` `; const HotkeyDiv = styled.div` - padding: 0 0 2rem 0; - flex-direction: row; - display: flex; + position: relative; align-items: center; + padding-top: 1rem; `; const SettingsBtn = styled.div` padding: 0; - margin-left: 1.5rem; width: 3rem; + position: absolute; + top: 0; + right: 0; cursor: pointer; color: white; background: transparent; @@ -51,7 +52,6 @@ export const HotkeysComponent = ({ return ( <> - Hotkeys diff --git a/src/components/production-line/production-line.tsx b/src/components/production-line/production-line.tsx index 96278c4..5bbbcf6 100644 --- a/src/components/production-line/production-line.tsx +++ b/src/components/production-line/production-line.tsx @@ -19,13 +19,11 @@ import { FormLabel, FormContainer, FormSelect, - PrimaryButton, StyledWarningMessage, } from "../landing-page/form-elements.tsx"; import { Spinner } from "../loader/loader.tsx"; import { DisplayContainerHeader } from "../landing-page/display-container-header.tsx"; import { DisplayContainer, FlexContainer } from "../generic-components.ts"; -import { useDeviceLabels } from "./use-device-labels.ts"; import { isBrowserFirefox, isMobile, @@ -50,20 +48,20 @@ import { VerifyDecision } from "../verify-decision/verify-decision.tsx"; import { ModalConfirmationText } from "../modal/modal-confirmation-text.ts"; import { SymphonyRtcConnectionComponent } from "./symphony-rtc-connection-component.tsx"; import { ReloadDevicesButton } from "../reload-devices-button.tsx/reload-devices-button.tsx"; -import { useFetchDevices } from "../../hooks/use-fetch-devices.ts"; import { HotkeysComponent } from "./hotkeys-component.tsx"; +import { CollapsableSection } from "./collapsable-section.tsx"; type FormValues = TJoinProductionOptions; -const TempDiv = styled.div` - padding: 0 0 2rem 0; -`; - const HeaderWrapper = styled.div` - padding: 2rem; display: flex; - flex-wrap: wrap; - align-items: center; + justify-content: space-between; +`; + +const ProductionLineInfo = styled.div` + font-size: 3rem; + font-weight: bold; + line-height: 1; `; const SmallText = styled.span` @@ -71,7 +69,7 @@ const SmallText = styled.span` `; const LargeText = styled.span` - word-break: break-all; + font-size: 2rem; `; const ButtonIcon = styled.div` @@ -128,12 +126,11 @@ const LongPressWrapper = styled.div` const ButtonWrapper = styled.div` display: flex; justify-content: space-between; - align-items: center; - margin: 0 2rem 2rem 1rem; `; const ListWrapper = styled(DisplayContainer)` width: 100%; + padding: 0; `; const StateText = styled.span<{ state: string }>` @@ -162,6 +159,26 @@ const IconWrapper = styled.div` height: 5rem; margin-left: 2rem; `; +const DeviceButtonWrapper = styled.div` + display: flex; + justify-content: flex-end; + + button { + margin: 0; + } + + .save-button { + margin-right: 1rem; + } +`; + +const StatusContainer = styled.div` + margin-bottom: 1rem; +`; + +const SpinnerWrapper = styled.div` + margin-top: 2rem; +`; type TProductionLine = { id: string; @@ -185,7 +202,6 @@ export const ProductionLine = ({ const [connectionActive, setConnectionActive] = useState(true); const [isInputMuted, setIsInputMuted] = useState(true); const [isOutputMuted, setIsOutputMuted] = useState(false); - const [showDeviceSettings, setShowDeviceSettings] = useState(false); const [confirmExitModalOpen, setConfirmExitModalOpen] = useState(false); const [value, setValue] = useState(0.75); const [hasReduced, setHasReduced] = useState(false); @@ -359,11 +375,6 @@ export const ProductionLine = ({ customKeyPress: savedHotkeys?.pushToTalkHotkey || "t", }); - const [refresh] = useFetchDevices({ - dispatch, - permission: true, - }); - useEffect(() => { if (joinProductionOptions) { setConnectionActive(true); @@ -522,8 +533,6 @@ export const ProductionLine = ({ const { loading, connectionError } = useIsLoading({ connectionState }); - const deviceLabels = useDeviceLabels({ joinProductionOptions }); - useCheckBadLineData({ joinProductionOptions, paramLineId, @@ -532,11 +541,6 @@ export const ProductionLine = ({ dispatch, }); - const settingsButtonPressed = () => { - refresh(); - setShowDeviceSettings(!showDeviceSettings); - }; - // Reset connection and re-connect to production-line const onSubmit: SubmitHandler = async (payload) => { if (joinProductionOptions && !audioNotChanged) { @@ -566,8 +570,6 @@ export const ProductionLine = ({ }, }, }); - - setShowDeviceSettings(false); } }; @@ -595,7 +597,13 @@ export const ProductionLine = ({ return ( <> - {!isSingleCall && ( + {!loading && production && line && ( + + {`${production.name}/`} + {line.name} + + )} + {!isSingleCall && production && line && ( setConfirmExitModalOpen(true)} /> {line?.programOutputLine && ( @@ -617,15 +625,6 @@ export const ProductionLine = ({ )} )} - - {!loading && production && line && ( - - Production: - {production.name} - Line: - {line.name} - - )} {connectionActive && ( @@ -638,20 +637,20 @@ export const ProductionLine = ({ )} {joinProductionOptions && connectionState && ( - - - - Status:{" "} - {connectionState} - - - + + + Status:{" "} + {connectionState} + + )} {joinProductionOptions && loading && (!connectionError ? ( - + + + ) : ( - Controls {!isIOSMobile && !isIpad && !( @@ -722,7 +720,6 @@ export const ProductionLine = ({ )} - {inputAudioStream && inputAudioStream !== "no-device" && !line?.programOutputLine && ( @@ -730,58 +727,35 @@ export const ProductionLine = ({ )} - - {deviceLabels?.inputLabel && - (line?.programOutputLine - ? joinProductionOptions.isProgramUser - : !joinProductionOptions.isProgramUser) && ( - - Audio Input: {deviceLabels.inputLabel} - - )} - - {deviceLabels?.outputLabel && - !( - line?.programOutputLine && joinProductionOptions.isProgramUser - ) && ( - - Audio Output: {deviceLabels.outputLabel} - - )} - - settingsButtonPressed()} - > - {!showDeviceSettings ? "Change device" : "Close"} - - - {showDeviceSettings && devices && ( + - {(line?.programOutputLine - ? joinProductionOptions.isProgramUser - : !joinProductionOptions.isProgramUser) && ( - - Input - - {devices.input && devices.input.length > 0 ? ( - devices.input.map((device) => ( - + + )} {!( line?.programOutputLine && joinProductionOptions.isProgramUser @@ -816,9 +790,10 @@ export const ProductionLine = ({ missing, please remove the permission and reload page. )} - + @@ -827,37 +802,40 @@ export const ProductionLine = ({ {!(isBrowserFirefox && !isMobile) && ( )} - + - )} - + {inputAudioStream && inputAudioStream !== "no-device" && !isMobile && !isTablet && ( - + + + )} + + {line && ( + )} + - {line && ( - - )} {confirmModalOpen && ( setConfirmModalOpen(false)}> Confirm diff --git a/src/components/production-line/user-list.tsx b/src/components/production-line/user-list.tsx index 640b99f..71a2b00 100644 --- a/src/components/production-line/user-list.tsx +++ b/src/components/production-line/user-list.tsx @@ -1,5 +1,4 @@ import styled from "@emotion/styled"; -import { DisplayContainerHeader } from "../landing-page/display-container-header.tsx"; import { TParticipant } from "./types.ts"; import { MicMuted, UserIcon } from "../../assets/icons/icon.tsx"; @@ -125,7 +124,6 @@ export const UserList = ({ return ( - Participants {participants.map((p) => { const isYou = p.sessionId === sessionId; diff --git a/src/components/user-settings/user-settings.tsx b/src/components/user-settings/user-settings.tsx index e096bdb..8e2c387 100644 --- a/src/components/user-settings/user-settings.tsx +++ b/src/components/user-settings/user-settings.tsx @@ -26,6 +26,11 @@ export const ResponsiveFormContainer = styled(FormContainer)` margin-top: 15rem; width: 50rem; } + + &.calls-page { + margin: 0; + padding: 2rem; + } `; export const ButtonWrapper = styled.div`