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
260 changes: 149 additions & 111 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"react-dom": "^18.3.1",
"swr": "^2.2.5",
"wavesurfer.js": "7.8.2",
"whip-whep": "1.2.0"
"whip-whep": "1.2.0",
"zustand": "^5.0.6"
},
"devDependencies": {
"@eslint/js": "^9.15.0",
Expand Down
44 changes: 35 additions & 9 deletions webapp/components/device.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@ import {
deviceNone,
deviceScreen,
} from '../lib/device'
import { deviceSpeakerAtom, speakerStatusAtom, settingsEnabledScreenAtom } from './../store/atom'
import { isScreenShareSupported } from '../lib/util'
import {
deviceSpeakerAtom,
speakerStatusAtom,
} from './../store/atom'

import Loading from './svg/loading'
import SvgSpeaker from './svg/speaker'
import SvgAudio from './svg/audio'
import SvgVideo from './svg/video'
import { SvgPresentCancel, SvgPresentToAll } from './svg/present'
import { SvgBackgroundCancel, SvgBackground } from './svg/background'
import { SvgSetting } from './svg/setting'
import Settings from './settings'

import {useSettingStore} from '../store/settingStore'

function toDevice(info: MediaDeviceInfo): Device {
const deviceId = info.deviceId
Expand All @@ -37,7 +45,7 @@ export default function DeviceBar(props: { streamId: string }) {
const [currentDeviceSpeaker, setCurrentDeviceSpeaker] = useAtom(deviceSpeakerAtom)
const [speakerStatus, setSpeakerStatus] = useAtom(speakerStatusAtom)

const [settingsEnabledScreen] = useAtom(settingsEnabledScreenAtom)
const screenShareButtonShowed = useSettingStore(state => state.screenShareButtonShowed)
const [virtualBackgroundEnabled, setVirtualBackgroundEnabled] = useState(false)

const {
Expand All @@ -55,6 +63,8 @@ export default function DeviceBar(props: { streamId: string }) {
const [deviceAudio, setDeviceAudio] = useState<Device[]>([deviceNone])
const [deviceVideo, setDeviceVideo] = useState<Device[]>([deviceNone])

const [isSetting, setIsSetting] = useState(false)

const permissionsQuery = async () =>
(await Promise.all(['camera', 'microphone'].map(
// NOTE:
Expand Down Expand Up @@ -117,7 +127,7 @@ export default function DeviceBar(props: { streamId: string }) {

setDeviceSpeaker([...speakers])
setDeviceAudio([...audios])
setDeviceVideo(settingsEnabledScreen ? [...videos] : [...videos, deviceScreen])
setDeviceVideo([...videos])
}

const init = async () => {
Expand Down Expand Up @@ -177,16 +187,25 @@ export default function DeviceBar(props: { streamId: string }) {
{ label: '1080p', value: '1080' },
{ label: 'Native', value: 'native' }
]
const [currentScreenResolution, setCurrentScreenResolution] = useState('720')
const screenShareResolution = useSettingStore(state => state.screenShareResolution)
const setScreenShareResolution = useSettingStore(state => state.setScreenShareResolution)

useEffect(() => {
if (userStatus.screen) {
onChangedDeviceVideo(deviceNone.deviceId)
}
}, [screenShareResolution])

const toggleEnableScreen = async () => {
const height = Number.parseInt(screenShareResolution)
const constraints = Number.isNaN(height) ? {} : { height }
setLoadingScreen(true)
await onChangedDeviceVideo(userStatus.screen ? deviceNone.deviceId : deviceScreen.deviceId)
await onChangedDeviceVideo(userStatus.screen ? deviceNone.deviceId : deviceScreen.deviceId, constraints)
setLoadingScreen(false)
}

const onChangeScreenShareResolution = async (resolution: string) => {
setCurrentScreenResolution(resolution)
setScreenShareResolution(resolution)
const height = Number.parseInt(resolution)
const constraints = Number.isNaN(height) ? {} : { height }
setLoadingScreen(true)
Expand Down Expand Up @@ -315,10 +334,10 @@ export default function DeviceBar(props: { streamId: string }) {
</button>
</section>
</center>
{!settingsEnabledScreen && (
{!screenShareButtonShowed && (
<center>
<section className="m-1 p-1 flex flex-row justify-center rounded-md border-1 border-indigo-500">
<button className="text-rose-400 rounded-md w-8 h-8" onClick={() => toggleEnableScreen()}>
<button className="text-rose-400 rounded-md w-8 h-8" onClick={() => toggleEnableScreen()} disabled={!isScreenShareSupported}>
<center>
{loadingScreen
? <Loading />
Expand All @@ -329,8 +348,9 @@ export default function DeviceBar(props: { streamId: string }) {
<div className="w-1"></div>
<select
className="w-3.5 h-8 rounded-sm rotate-180"
value={currentScreenResolution}
value={screenShareResolution}
onChange={e => onChangeScreenShareResolution(e.target.value)}
disabled={!isScreenShareSupported}
>
{screenResolutions.map(r =>
<option key={r.label} value={r.value}>{r.label}</option>
Expand All @@ -339,6 +359,12 @@ export default function DeviceBar(props: { streamId: string }) {
</section>
</center>
)}
<div className="flex flex-row justify-center m-1 p-1 rounded-md border-1 border-indigo-500">
<button className="flex justify-center items-center text-rose-400 rounded-md w-8 h-8" onClick={() => setIsSetting(true)}>
<SvgSetting />
</button>
</div>
{isSetting && <Settings onClose={() => setIsSetting(false)} />}
</div>
)
}
5 changes: 5 additions & 0 deletions webapp/components/join.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import {
} from '../store/atom'
import { getStorage, setStorage, delStorage, setStorageStream, setStorageMeeting } from '../lib/storage'
import { newRoom, newUser, setApiToken, setRoomId } from '../lib/api'
import { SvgSetting } from './svg/setting'
import Settings from './settings'

export default function Join() {
const [loc, setLoc] = useAtom(locationAtom)
const [__, setAtomMeetingId] = useAtom(meetingIdAtom)
const [tmpId, setTmpId] = useState<string>('')
const [isSetting, setIsSetting] = useState(false)

const getLoginStatus = async () => {
const user = getStorage()
Expand Down Expand Up @@ -67,11 +70,13 @@ export default function Join() {
maxLength={11}
/>
<button className="btn-primary my-2" disabled={!tmpId} onClick={() => { joinMeeting() }}>Join</button>
<button className="btn-primary my-2 ml-2" onClick={() => setIsSetting(true)}><SvgSetting /></button>
</center>
<center className="flex flex-row flex-wrap justify-center text-white">
<p>If have some problems, Please click this:</p>
<a className="mx-2 text-red-300 underline" onClick={delStorage}>Reset</a>
</center>
{isSetting && <Settings onClose={() => setIsSetting(false)} />}
</div>
)
}
Loading