diff --git a/packages/call/src/components/actions.tsx b/packages/call/src/components/actions.tsx index 6ff4661..b4e1311 100644 --- a/packages/call/src/components/actions.tsx +++ b/packages/call/src/components/actions.tsx @@ -24,6 +24,7 @@ import { ChevronUp, Maximize, Minimize, + ScreenShareOff, SquareArrowOutDownLeft, SquareArrowOutUpRight, } from "lucide-react"; @@ -96,68 +97,56 @@ export default function Actions() { - - - } - /> - - Mute - - - - - } - /> - - Deafen - - - - - } - /> - - Screenshare - - - - - } - /> - - Invite - - + + + + {isWatchingFocusedStream ? ( - + + stopWatchingFocusedStream()} + > + + + } + /> + + Stop watching + + ) : ( - + )} diff --git a/packages/call/src/components/buttons/deaf.tsx b/packages/call/src/components/buttons/deaf.tsx index 4c12c43..42dd3f4 100644 --- a/packages/call/src/components/buttons/deaf.tsx +++ b/packages/call/src/components/buttons/deaf.tsx @@ -1,17 +1,21 @@ -import { Button } from "@tensamin/ui"; +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@tensamin/ui"; import { toggleDeaf, useCall } from "../../store"; import { HeadphoneOff, Headphones } from "lucide-react"; export default function DeafButton({ className, iconSize, + tooltip, + portalContainer, }: { className?: string; iconSize?: number; + tooltip?: string; + portalContainer?: HTMLElement; }) { const deaf = useCall((state) => state.deaf); - return ( + const button = ( - } - /> - - {contacts.map((contact) => ( - Loading...} - component={(user) => ( - + } + /> + ) : ( + - )} - /> - ))} - - + ) + } + /> + + {contacts.map((contact) => ( + Loading...} + component={(user) => ( + + )} + /> + ))} + + + {tooltip && ( + + {tooltip} + + )} + ); } diff --git a/packages/call/src/components/buttons/leave.tsx b/packages/call/src/components/buttons/leave.tsx index ac38546..364b4be 100644 --- a/packages/call/src/components/buttons/leave.tsx +++ b/packages/call/src/components/buttons/leave.tsx @@ -1,17 +1,21 @@ import { LeaveIcon } from "@livekit/components-react"; -import { Button } from "@tensamin/ui"; +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@tensamin/ui"; import { disconnect, useCall } from "../../store"; export default function LeaveButton({ className, iconSize, + tooltip, + portalContainer, }: { className?: string; iconSize?: number; + tooltip?: string; + portalContainer?: HTMLElement; }) { const state = useCall((store) => store.state); - return ( + const button = ( ); + + if (!tooltip) { + return button; + } + + return ( + + + + {tooltip} + + + ); } diff --git a/packages/call/src/components/buttons/mute.tsx b/packages/call/src/components/buttons/mute.tsx index 75125fa..c8f2ba0 100644 --- a/packages/call/src/components/buttons/mute.tsx +++ b/packages/call/src/components/buttons/mute.tsx @@ -1,17 +1,21 @@ -import { Button } from "@tensamin/ui"; +import { Button, Tooltip, TooltipContent, TooltipTrigger } from "@tensamin/ui"; import { toggleMute, useCall } from "../../store"; import { Mic, MicOff } from "lucide-react"; export default function MuteButton({ className, iconSize, + tooltip, + portalContainer, }: { className?: string; iconSize?: number; + tooltip?: string; + portalContainer?: HTMLElement; }) { const micEnabled = useCall((state) => state.micEnabled); - return ( + const button = ( + } /> ) : ( - - )} + + ) + } + /> + + - } - /> - - - - - - + + + + + {tooltip && ( + + {tooltip} + + )} + {isTauri() && ( store.state); const isEncrypted = useCall((store) => store.isEncrypted); const callId = useCall((store) => store.callId); diff --git a/packages/call/src/store.tsx b/packages/call/src/store.tsx index 4e95c43..e605ece 100644 --- a/packages/call/src/store.tsx +++ b/packages/call/src/store.tsx @@ -509,9 +509,7 @@ export function setCallView(view: CallView) { useCall.setState({ view }); } -export function setUsersInFocusedViewHidden( - usersInFocusedViewHidden: boolean, -) { +export function setUsersInFocusedViewHidden(usersInFocusedViewHidden: boolean) { useCall.setState((state) => ({ usersInFocusedViewHidden, layoutVersion: diff --git a/packages/call/src/views/main/focused.tsx b/packages/call/src/views/main/focused.tsx index 07c1dae..d52362b 100644 --- a/packages/call/src/views/main/focused.tsx +++ b/packages/call/src/views/main/focused.tsx @@ -107,7 +107,9 @@ export default function View() { let frameId = 0; const syncTileLayout = () => { - const containerWidth = Math.floor(container.getBoundingClientRect().width); + const containerWidth = Math.floor( + container.getBoundingClientRect().width, + ); const tileWidth = Math.floor(focusedTile.getBoundingClientRect().width); setIsFocusedTileFlush(Math.abs(containerWidth - tileWidth) <= 1); @@ -155,14 +157,10 @@ export default function View() { const focusedParticipant = getParticipantById(focusedParticipantId); const focusedParticipantHasActiveScreenShare = activeScreenShareParticipantIdSet.has(focusedParticipantId); - const isImmersiveFocusedView = - callIsFullscreen && usersInFocusedViewHidden; + const isImmersiveFocusedView = callIsFullscreen && usersInFocusedViewHidden; return ( -
+
(null); const topBarRef = useRef(null); const actionsRef = useRef(null); - const hideChromeTimeoutRef = useRef | null>(null); + const hideChromeTimeoutRef = useRef | null>( + null, + ); const [overlayInsets, setOverlayInsets] = useState({ top: 0, bottom: 0 }); - const [isImmersiveChromeVisible, setIsImmersiveChromeVisible] = useState(false); + const [isImmersiveChromeVisible, setIsImmersiveChromeVisible] = + useState(false); useEffect(() => { setScreenRef(screenRef); @@ -102,7 +105,7 @@ export default function Layout({ children }: { children: React.ReactNode }) { ref={screenRef} className={`relative w-full h-full flex flex-col ${ isImmersiveFocusedView && !immersiveChromeVisible ? "cursor-none" : "" - }`} + } ${callIsFullscreen ? "bg-background" : ""}`} onMouseEnter={showImmersiveChrome} onMouseMove={showImmersiveChrome} onMouseLeave={hideImmersiveChrome}