Skip to content

Commit

Permalink
feat: collapsablecalls
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasMaupin committed Jan 15, 2025
1 parent 2ab7509 commit 5927935
Show file tree
Hide file tree
Showing 10 changed files with 491 additions and 382 deletions.
3 changes: 3 additions & 0 deletions src/assets/icons/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Add from "./add.svg?react";
import Edit from "./edit.svg?react";
import TV from "./tv.svg?react";
import Megaphone from "./campaign.svg?react";
import Logout from "./logout.svg?react";

export const MicMuted = () => <MicMute />;

Expand Down Expand Up @@ -55,3 +56,5 @@ export const EditIcon = () => <Edit />;
export const TVIcon = () => <TV />;

export const MegaphoneIcon = () => <Megaphone />;

export const LogoutIcon = () => <Logout />;
1 change: 1 addition & 0 deletions src/assets/icons/logout.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 75 additions & 85 deletions src/components/calls-page/calls-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,38 @@ import { useNavigate, useParams } from "react-router-dom";
import { useGlobalState } from "../../global-state/context-provider";
import { JoinProduction } from "../landing-page/join-production";
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 { MicMuted, MicUnmuted } from "../../assets/icons/icon";
import { useGlobalHotkeys } from "../production-line/use-line-hotkeys";
import { ProductionLine } from "../production-line/production-line";
import { PageHeader } from "../page-layout/page-header";
import { isMobile } from "../../bowser";

const Container = styled.div`
display: flex;
flex-direction: column;
flex-wrap: wrap;
padding: 2rem;
`;

const CallsContainer = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
gap: 2rem;
padding: 0 2rem 2rem 2rem;
form {
margin: 0;
}
`;

const CallContainer = styled.div`
display: flex;
flex-direction: column;
padding: 2rem;
max-width: 40rem;
min-width: 30rem;
`;

const AddCallContainer = styled.div`
display: flex;
`;

const ButtonWrapper = styled.div`
display: flex;
justify-content: space-between;
height: 4rem;
`;

const MuteAllCallsBtn = styled(PrimaryButton)`
background: rgba(50, 56, 59, 1);
color: #6fd84f;
Expand All @@ -70,7 +58,7 @@ const MuteAllCallsBtn = styled(PrimaryButton)`
}
`;

const HeaderRightSide = styled.div`
const HeaderButtons = styled.div`
display: flex;
`;

Expand Down Expand Up @@ -146,31 +134,32 @@ export const CallsPage = () => {
};

return (
<Container>
<ButtonWrapper>
<NavigateToRootButton
resetOnExitRequest={() => {
if (isEmpty) {
runExitAllCalls();
} else {
setConfirmExitModalOpen(true);
}
}}
/>
<HeaderRightSide>
{confirmExitModalOpen && (
<Modal onClose={() => setConfirmExitModalOpen(false)}>
<DisplayContainerHeader>Confirm</DisplayContainerHeader>
<ModalConfirmationText>
Are you sure you want to leave all calls?
</ModalConfirmationText>
<VerifyDecision
confirm={runExitAllCalls}
abort={() => setConfirmExitModalOpen(false)}
/>
</Modal>
)}
{!isEmpty && !isSingleCall && (
<>
<PageHeader
title={!isEmpty ? "Calls" : ""}
hasNavigateToRoot
onNavigateToRoot={() => {
if (isEmpty) {
runExitAllCalls();
} else {
setConfirmExitModalOpen(true);
}
}}
>
{confirmExitModalOpen && (
<Modal onClose={() => setConfirmExitModalOpen(false)}>
<DisplayContainerHeader>Confirm</DisplayContainerHeader>
<ModalConfirmationText>
Are you sure you want to leave all calls?
</ModalConfirmationText>
<VerifyDecision
confirm={runExitAllCalls}
abort={() => setConfirmExitModalOpen(false)}
/>
</Modal>
)}
<HeaderButtons>
{!isEmpty && !isSingleCall && !isMobile && (
<MuteAllCallsBtn
type="button"
onClick={() => setIsMasterInputMuted(!isMasterInputMuted)}
Expand All @@ -182,53 +171,54 @@ export const CallsPage = () => {
)}
{!isEmpty && (
<AddCallContainer>
<ButtonWrapper>
<SecondaryButton
type="button"
onClick={() => setAddCallActive(!addCallActive)}
>
Add Call
</SecondaryButton>
</ButtonWrapper>
<SecondaryButton
type="button"
onClick={() => setAddCallActive(!addCallActive)}
>
Add Call
</SecondaryButton>
</AddCallContainer>
)}
</HeaderRightSide>
</ButtonWrapper>
{isEmpty && paramProductionId && paramLineId && (
<JoinProduction
preSelected={{
preSelectedProductionId: paramProductionId,
preSelectedLineId: paramLineId,
}}
customGlobalMute={customGlobalMute}
/>
)}
<CallsContainer>
{Object.entries(calls).map(
([callId, callState]) =>
callId &&
callState.joinProductionOptions && (
<CallContainer key={callId}>
<ProductionLine
id={callId}
shouldReduceVolume={shouldReduceVolume}
callState={callState}
isSingleCall={isSingleCall}
customGlobalMute={customGlobalMute}
masterInputMute={isMasterInputMuted}
/>
</CallContainer>
)
)}
{addCallActive && productionId && (
</HeaderButtons>
</PageHeader>
<Container>
{isEmpty && paramProductionId && paramLineId && (
<JoinProduction
preSelected={{
preSelectedProductionId: paramProductionId,
preSelectedLineId: paramLineId,
}}
customGlobalMute={customGlobalMute}
addAdditionalCallId={productionId}
closeAddCallView={() => setAddCallActive(false)}
className="calls-page"
/>
)}
</CallsContainer>
</Container>
<CallsContainer>
{addCallActive && productionId && (
<JoinProduction
customGlobalMute={customGlobalMute}
addAdditionalCallId={productionId}
closeAddCallView={() => setAddCallActive(false)}
className="calls-page"
/>
)}
{Object.entries(calls)
.toReversed()
.map(
([callId, callState]) =>
callId &&
callState.joinProductionOptions && (
<ProductionLine
key={callId}
id={callId}
shouldReduceVolume={shouldReduceVolume}
callState={callState}
isSingleCall={isSingleCall}
customGlobalMute={customGlobalMute}
masterInputMute={isMasterInputMuted}
/>
)
)}
</CallsContainer>
</Container>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ const StyledBackBtn = styled.div`
`;

export const NavigateToRootButton = ({
resetOnExitRequest,
onNavigate,
}: {
resetOnExitRequest?: () => void;
onNavigate?: () => void;
}) => {
const navigate = useNavigate();

return (
<StyledBackBtn
onClick={() => {
if (resetOnExitRequest) {
resetOnExitRequest();
if (onNavigate) {
onNavigate();
} else {
navigate("/");
}
Expand Down
11 changes: 9 additions & 2 deletions src/components/page-layout/page-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,25 @@ const RootButtonWrapper = styled.div`
interface PageHeaderProps extends PropsWithChildren {
title: string;
hasNavigateToRoot?: boolean;
onNavigateToRoot?: () => void;
loading?: boolean;
}

export const PageHeader: FC<PageHeaderProps> = (props) => {
const { title, hasNavigateToRoot = false, loading = false, children } = props;
const {
title,
hasNavigateToRoot = false,
onNavigateToRoot,
loading = false,
children,
} = props;

return (
<HeaderContainer>
<HeaderLeftSide>
{hasNavigateToRoot && (
<RootButtonWrapper>
<NavigateToRootButton />
<NavigateToRootButton onNavigate={onNavigateToRoot} />
</RootButtonWrapper>
)}
<CustomContainerHeader>{title}</CustomContainerHeader>
Expand Down
2 changes: 1 addition & 1 deletion src/components/production-line/collapsable-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const SectionWrapper = styled.div`
border: 0.2rem #6d6d6d solid;
border-radius: 1rem;
padding: 1rem;
margin-bottom: 1rem;
margin-top: 1rem;
`;

const SectionHeader = styled.div`
Expand Down
23 changes: 17 additions & 6 deletions src/components/production-line/exit-call-button.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import styled from "@emotion/styled";
import { RemoveIcon } from "../../assets/icons/icon";
import { LogoutIcon } from "../../assets/icons/icon";
import { PrimaryButton } from "../landing-page/form-elements";

const StyledBackBtn = styled(PrimaryButton)`
padding: 0;
margin: 0;
width: 4rem;
background: #32383b;
margin-top: 1rem;
background: rgba(50, 56, 59, 1);
color: white;
border: 0.2rem solid #6d6d6d;
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
svg {
width: 2.5rem;
height: 2.5rem;
fill: #f96c6c;
}
`;

const ButtonText = styled.div`
line-height: 2.4rem;
`;

export const ExitCallButton = ({
resetOnExit,
}: {
Expand All @@ -25,7 +35,8 @@ export const ExitCallButton = ({
title="Exit call"
onClick={() => resetOnExit()}
>
<RemoveIcon />
<ButtonText>Leave Call</ButtonText>
<LogoutIcon />
</StyledBackBtn>
);
};
4 changes: 3 additions & 1 deletion src/components/production-line/long-press-to-talk-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { isMobile } from "../../bowser";

type TLongPressToTalkButton = {
muteInput: (input: boolean) => void;
text?: string;
};

const Button = styled(PrimaryButton)`
Expand Down Expand Up @@ -35,6 +36,7 @@ const Button = styled(PrimaryButton)`

export const LongPressToTalkButton = ({
muteInput,
text = "Push To Talk",
}: TLongPressToTalkButton) => {
const [isToggled, setIsToggled] = useState(false);
const [longPressTimeout, setLongPressTimeout] =
Expand Down Expand Up @@ -90,7 +92,7 @@ export const LongPressToTalkButton = ({
width: "100%",
}}
>
Push to Talk
{text}
</span>
</Button>
);
Expand Down
Loading

0 comments on commit 5927935

Please sign in to comment.