Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,30 @@
opacity: 0;
}
}

/* Chrome / Edge */
video::-webkit-media-controls {
display: none !important;
}

:fullscreen video::-webkit-media-controls {
display: none !important;
}

video::-webkit-media-controls-enclosure {
display: none !important;
}

/* Safari / iOS */
video::-webkit-media-controls-panel {
display: none !important;
}

:-webkit-full-screen video::-webkit-media-controls {
display: none !important;
}

/* Firefox */
video::-moz-media-controls {
display: none !important;
}
40 changes: 40 additions & 0 deletions src/components/modals/fullscreen-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Dialog, DialogContent } from '../ui/dialog';

const FullScreenModal = () => {
// const { getTrack, getConsumer } = useMedia();
// const peerMe = usePeerMe();
// const videoRef = useRef<HTMLVideoElement>(null);

// const fullscreenActive = useFullscreenActive();
// const fullscreenActions = useFullscreenActions();
// const selectedPeerId = usePeerSelectedId();

// useEffect(() => {
// if (!selectedPeerId || !videoRef.current)
// return console.log('return screen');
// let track;
// const source =
// fullscreenActive === FullscreenType.Screen ? 'screen' : 'camera';
// if (selectedPeerId === peerMe?.id) {
// track = getTrack(source);
// } else {
// const consumer = getConsumer(selectedPeerId, source);
// track = consumer?.track;
// }

// if (!track) return console.log('return screen 2');

// console.log('got here');

// const stream = new MediaStream([track]);
// videoRef.current.srcObject = stream;
// }, [getConsumer, getTrack, selectedPeerId, fullscreenActive, peerMe?.id]);

return (
<Dialog open={false}>
<DialogContent className="max-w-full sm:max-w-full h-full rounded-none border-0 p-0 "></DialogContent>
</Dialog>
);
};

export default FullScreenModal;
14 changes: 12 additions & 2 deletions src/components/room/display/screen-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { Maximize2, MonitorUp } from 'lucide-react';
const ScreenView = () => {
const { getTrack, getConsumer } = useMedia();
const [aspectRatio, setAspectRatio] = useState(0);
// const fullscreenActions = useFullscreenActions();

// const peerActions = usePeerActions();
const peerScreens = usePeerScreens();
const screenOn = useScreenOn();
const peerMe = usePeerMe();
Expand Down Expand Up @@ -44,14 +46,21 @@ const ScreenView = () => {
videoRef.current.srcObject = stream;
}, [peerId, getConsumer, getTrack, screenOn]);

const openFullscreen = () => {
videoRef.current?.requestFullscreen();
};

if (!peerId) return null;
return (
<div
className={cn(
'relative bg-linear-to-br from-white/5 to-white/2 rounded-2xl h-1/2 lg:h-full w-full overflow-hidden'
)}
>
<div className=" cursor-pointer absolute h-fit bg-black/30 hover:bg-black/50 right-2 top-2 rounded-md p-2 ">
<div
onClick={openFullscreen}
className=" cursor-pointer absolute z-10 h-fit bg-black/50 hover:bg-black/60 right-2 top-2 rounded-md p-2 "
>
<Maximize2 size={16} />
</div>
<div
Expand All @@ -62,10 +71,11 @@ const ScreenView = () => {
>
<video
ref={videoRef}
className=" object-cover "
// className=" object-cover "
autoPlay
muted
playsInline
controls={false}
webkit-playsinline="true"
/>

Expand Down
2 changes: 1 addition & 1 deletion src/components/room/grid/my-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const MyScreen = () => {
if (!track) return;
const ratio =
Math.round((track.getSettings().aspectRatio || 1 / 1) * 10) / 10;
console.log('track- size =>', ratio, '=>', track.getSettings().aspectRatio);
// console.log('track- size =>', ratio, '=>', track.getSettings().aspectRatio);
setAspectRatio(ratio);
const stream = new MediaStream([track]);
videoRef.current.srcObject = stream;
Expand Down
6 changes: 3 additions & 3 deletions src/components/room/grid/my-tile.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useRef } from 'react';
import { Hand, Mic, MicOff } from 'lucide-react';
import type { Layout } from '@/types';
import { cn, getInitials, getPeerId } from '@/lib/utils';
import { cn, getInitials, getPeerId, isMobileDevice } from '@/lib/utils';
import {
useCameraDeviceId,
useCameraOn,
Expand All @@ -25,6 +25,7 @@ const MyTile: React.FC<PeerTileProps> = ({ layout }) => {
const cameraDeviceId = useCameraDeviceId();
const peerMe = usePeerMe();
const peerMeCondition = usePeerConditionsById(peerMe?.id || getPeerId());
const isAMobileDevice = isMobileDevice();

useEffect(() => {
if (!cameraOn || !videoRef.current) return;
Expand All @@ -49,8 +50,7 @@ const MyTile: React.FC<PeerTileProps> = ({ layout }) => {
<video
ref={videoRef}
className={cn(
'w-full h-full relative z-10 scale-x-[-1]',
!peerMe.isMobileDevice && 'object-cover'
isAMobileDevice ? 'object-contain' : ' h-full w-full object-cover'
)}
autoPlay
muted
Expand Down
2 changes: 1 addition & 1 deletion src/components/room/grid/peer-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const PeerScreen = () => {
if (!consumer) return;

const { track } = consumer;
console.log('track- size =>', track.getSettings().aspectRatio);
// console.log('track- size =>', track.getSettings().aspectRatio);
const stream = new MediaStream([track]);
videoRef.current.srcObject = stream;
}, [peerId, getConsumer]);
Expand Down
9 changes: 7 additions & 2 deletions src/components/room/grid/peer-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const PeerTile: React.FC<PeerTileProps> = ({ peerId, layout }) => {

if (!peerData) return null;

// const openFullscreen = () => {
// videoRef.current?.requestFullscreen().catch(error => console.log(error));
// };

return (
<div
className={cn(
Expand All @@ -49,8 +53,9 @@ export const PeerTile: React.FC<PeerTileProps> = ({ peerId, layout }) => {
<video
ref={videoRef}
className={cn(
'w-full h-full relative z-10',
!peerData.isMobileDevice && 'object-cover'
peerData?.isMobileDevice
? 'object-contain'
: ' h-full w-full object-cover'
)}
autoPlay
muted
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/use-room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const useRoom = () => {
const peers = result?.peers;
peerActions.clear();
if (peers) {
console.log(peers);
peerActions.addOthersData(peers);
}
},
Expand Down Expand Up @@ -103,6 +104,7 @@ export const useRoom = () => {
() => ({
[Actions.PeerAdded]: async args => {
const data = ValidationSchema.peerData.parse(args);

peerActions.addData(data);
},

Expand Down
6 changes: 2 additions & 4 deletions src/lib/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ const peerDataSchema = z.object({
email: z.string().optional(),
photo: z.string().optional(),
color: z.string().optional(),
isMobileDevice: z.boolean().optional(),
});

export const ValidationSchema = {
peerData: z.object({
id: z.string(),
name: z.string(),
}),
peerData: peerDataSchema,
peerId: z.object({
id: z.string(),
}),
Expand Down
2 changes: 2 additions & 0 deletions src/pages/room/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Conference from './conference';
import { Helmet } from 'react-helmet';
import SettingsModal from '@/components/modals/settings-modal';
import CautionModal from '@/components/modals/caution-modal';
import FullScreenModal from '@/components/modals/fullscreen-modal';

const Room = () => {
const roomAccess = useRoomAccess();
Expand All @@ -23,6 +24,7 @@ const Room = () => {
{roomAccess === Access.Allowed ? <Conference /> : <JoinRoom />}
<SettingsModal />
<CautionModal />
<FullScreenModal />
</RoomProvider>
</ServiceProvider>
</>
Expand Down
16 changes: 16 additions & 0 deletions src/store/conf/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export const useScreenActions = () =>
export const usePeerMe = () => useConfStore(state => state.peers.me);
export const usePeerOthers = () => useConfStore(state => state.peers.others);
export const usePeerScreens = () => useConfStore(state => state.peers.screens);
export const usePeerSelectedId = () =>
useConfStore(state => state.peers.selectedId);
export const usePeerOthersById = (id: string) =>
useConfStore(state => state.peers.others[id]);
export const usePeerOthersKeys = () => {
Expand Down Expand Up @@ -98,6 +100,7 @@ export const usePeerActions = () =>
swapPositions: useConfStore.getState().peers.swapPositions,
addScreen: useConfStore.getState().peers.addScreen,
removeScreen: useConfStore.getState().peers.removeScreen,
setSelectedId: useConfStore.getState().peers.setSelectedId,
remove: useConfStore.getState().peers.remove,
clear: useConfStore.getState().peers.clear,
}),
Expand Down Expand Up @@ -229,3 +232,16 @@ export const useCautionActions = () =>
}),
[]
);

// ============================================================================
// FULLSCREEN SELECTORS
// ============================================================================
export const useFullscreenActive = () =>
useConfStore(state => state.fullscreen.active);
export const useFullscreenActions = () =>
useMemo(
() => ({
set: useConfStore.getState().fullscreen.set,
}),
[]
);
2 changes: 2 additions & 0 deletions src/store/conf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { createSettingsSlice } from './slices/settings-slice';
import { createReactionSlice } from './slices/reaction-slice';
import { createHandSlice } from './slices/hand-slice';
import { createCautionSlice } from './slices/caution-slice';
import { createFullscreenSlice } from './slices/fullscreen-slice';

export const useConfStore = create<ConfStoreState>()(
devtools(
Expand All @@ -30,6 +31,7 @@ export const useConfStore = create<ConfStoreState>()(
settings: createSettingsSlice(set, get, api),
reactions: createReactionSlice(set, get, api),
caution: createCautionSlice(set, get, api),
fullscreen: createFullscreenSlice(set, get, api),
})),
{ name: 'conf-store' }
)
Expand Down
22 changes: 22 additions & 0 deletions src/store/conf/slices/fullscreen-slice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { StateCreator } from 'zustand';
import type { ConfStoreState } from '../type';
import { FullscreenType } from '@/types';

export interface FullscreenSlice {
active: FullscreenType;
set: (active: FullscreenType) => void;
}

export const createFullscreenSlice: StateCreator<
ConfStoreState,
[],
[['zustand/immer', FullscreenSlice]],
FullscreenSlice
> = set => ({
active: FullscreenType.Hide,
set: active =>
set(state => {
state.fullscreen.active = active;
return state;
}),
});
9 changes: 8 additions & 1 deletion src/store/conf/slices/peer-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface PeerSlice {
id: string;
lastActiveSpeechTimestamp: number;
}[]; // id and array position;

selectedId: string | null;
screens: string[]; // ids of peers sharing screen -> for optimization
//Actions
addData: (data: PeerData, isMe?: boolean) => void;
Expand All @@ -21,6 +21,7 @@ export interface PeerSlice {
updateCondition: (id: string, condition: Partial<PeerCondition>) => void;
updateLastActiveSpeechTimestamp: (id: string, timeStamp: number) => void;
swapPositions: (activeIndex: number, passiveIndex: number) => void;
setSelectedId: (id: string | null) => void;
addScreen: (id: string) => void;
removeScreen: (id: string) => void;
remove: (id: string) => void;
Expand All @@ -38,6 +39,7 @@ export const createPeerSlice: StateCreator<
medias: {},
conditions: {},
positions: [],
selectedId: null,
screens: [],
addData: (data, isYou = false) =>
set(state => {
Expand Down Expand Up @@ -136,6 +138,11 @@ export const createPeerSlice: StateCreator<
}
return state;
}),
setSelectedId: id =>
set(state => {
state.peers.selectedId = id;
return state;
}),
remove: id =>
set(state => {
delete state.peers.others[id];
Expand Down
2 changes: 2 additions & 0 deletions src/store/conf/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { SettingsSlice } from './slices/settings-slice';
import type { ReactionSlice } from './slices/reaction-slice';
import type { HandSlice } from './slices/hand-slice';
import type { CautionSlice } from './slices/caution-slice';
import type { FullscreenSlice } from './slices/fullscreen-slice';

export interface ConfStoreState {
mic: MicSlice;
Expand All @@ -24,4 +25,5 @@ export interface ConfStoreState {
settings: SettingsSlice;
reactions: ReactionSlice;
caution: CautionSlice;
fullscreen: FullscreenSlice;
}
5 changes: 5 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export enum CautionType {
RemovePeer = 'REMOVE_PEER',
Hide = 'HIDE',
}
export enum FullscreenType {
Camera = 'CAMERA',
Screen = 'SCREEN',
Hide = 'HIDE',
}

export type AppData = {
[key: string]: unknown;
Expand Down
Loading