mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
selecting webrtc device
This commit is contained in:
parent
0b4e7da468
commit
9af0fc744f
@ -176,6 +176,10 @@ export const en = {
|
||||
editMembership: 'Edit Membership',
|
||||
deleteTopic: 'Delete Topic',
|
||||
leaveTopic: 'Leave Topic',
|
||||
|
||||
integrated: 'Integrated',
|
||||
microphone: 'Microphone',
|
||||
camera: 'Camera'
|
||||
};
|
||||
|
||||
export const fr = {
|
||||
@ -356,5 +360,9 @@ export const fr = {
|
||||
editMembership: 'Modifier Membres du Suject',
|
||||
deleteTopic: 'Supprimer le Sujet',
|
||||
leaveTopic: 'Quitter le Suject',
|
||||
|
||||
integrated: 'Intégré',
|
||||
microphone: 'Microphone',
|
||||
camera: 'Caméra'
|
||||
};
|
||||
|
||||
|
@ -164,6 +164,9 @@ export function useRingContext() {
|
||||
};
|
||||
|
||||
try {
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
console.log('>> ', devices);
|
||||
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: false,
|
||||
audio: true,
|
||||
@ -417,6 +420,9 @@ export function useRingContext() {
|
||||
},
|
||||
enableVideo: async () => {
|
||||
if (!accessVideo.current) {
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
console.log('>> ', devices);
|
||||
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: true,
|
||||
@ -457,6 +463,24 @@ export function useRingContext() {
|
||||
updateState({ localAudio: false });
|
||||
}
|
||||
},
|
||||
getDevices: async (type) => {
|
||||
const filtered = new Map();
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
devices.filter(item => item.kind === type + 'input').forEach(item => {
|
||||
if (item && item.label) {
|
||||
const entry = filtered.get(item.groupId);
|
||||
if (entry) {
|
||||
if (item.label && item.label.length < entry.label.length) {
|
||||
filtered.set(item.groupId, item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
filtered.set(item.groupId, item);
|
||||
}
|
||||
}
|
||||
});
|
||||
return Array.from(filtered.values());
|
||||
},
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
|
@ -18,6 +18,10 @@ export function useSettingsContext() {
|
||||
strings: en,
|
||||
dateFormat: 'mm/dd',
|
||||
timeFormat: '12h',
|
||||
audioInput: null,
|
||||
audioInputs: [],
|
||||
videoInput: null,
|
||||
videoInputs: [],
|
||||
});
|
||||
|
||||
const SMALL_MEDIUM = 650;
|
||||
@ -43,6 +47,36 @@ export function useSettingsContext() {
|
||||
}
|
||||
};
|
||||
|
||||
const getDevices = async (type) => {
|
||||
const filtered = new Map();
|
||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||
|
||||
devices.filter(item => item.kind === type + 'input').forEach(item => {
|
||||
if (item) {
|
||||
const label = item.label ? item.label : state.strings.integrated;
|
||||
const entry = filtered.get(item.groupId);
|
||||
if (entry) {
|
||||
if (item.label && label.length < entry.label.length) {
|
||||
filtered.set(item.groupId, { value: item.deviceId, label });
|
||||
}
|
||||
}
|
||||
else {
|
||||
filtered.set(item.groupId, { value: item.deviceId, label });
|
||||
}
|
||||
}
|
||||
});
|
||||
return Array.from(filtered.values());
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getDevices('audio').then(audio => {
|
||||
updateState({ audioInputs: audio });
|
||||
});
|
||||
getDevices('video').then(video => {
|
||||
updateState({ videoInputs: video });
|
||||
});
|
||||
}, [state.strings]);
|
||||
|
||||
useEffect(() => {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
setTimeout(handleResize, 100 * i); //cludge for my mobile browser
|
||||
@ -100,6 +134,10 @@ export function useSettingsContext() {
|
||||
}
|
||||
}
|
||||
|
||||
const audioInput = localStorage.getItem('audio_input');
|
||||
const videoInput = localStorage.getItem('video_input');
|
||||
updateState({ audioInput, videoInput });
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
window.removeEventListener('orientationchange', handleResize);
|
||||
@ -155,6 +193,14 @@ export function useSettingsContext() {
|
||||
localStorage.setItem('time_format', timeFormat);
|
||||
updateState({ timeFormat });
|
||||
},
|
||||
setAudioInput: (audioInput) => {
|
||||
localStorage.setItem('audio_input', audioInput);
|
||||
updateState({ audioInput });
|
||||
},
|
||||
setVideoInput: (videoInput) => {
|
||||
localStorage.setItem('video_input', videoInput);
|
||||
updateState({ videoInput });
|
||||
},
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
|
@ -135,13 +135,13 @@ export function Profile({ closeProfile }) {
|
||||
</div>
|
||||
{ state.display !== 'xlarge' && state.displaySet && (
|
||||
<div className="rightAccess">
|
||||
<AccountAccess />
|
||||
{ state.display === 'small' && (
|
||||
<div className="logout" onClick={logout}>
|
||||
<LogoutOutlined />
|
||||
<div className="label">{ state.strings.logout }</div>
|
||||
<div className="logout">
|
||||
<LogoutOutlined className="icon" onClick={logout} />
|
||||
<div className="label" onClick={logout}>{ state.strings.logout }</div>
|
||||
</div>
|
||||
)}
|
||||
<AccountAccess />
|
||||
<div className="contentFill" />
|
||||
</div>
|
||||
)}
|
||||
|
@ -205,14 +205,18 @@ export const ProfileWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
color: ${props => props.theme.mainText};
|
||||
background-color: ${props => props.theme.modalArea};
|
||||
background-color: ${props => props.theme.selectedArea};
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
justify-content: center;
|
||||
|
||||
.icon {
|
||||
color: ${props => props.theme.alertText};
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.label {
|
||||
cursor: pointer;
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,29 @@ export function AccountAccess() {
|
||||
return (
|
||||
<AccountAccessWrapper>
|
||||
{ modalContext }
|
||||
<div className="account">
|
||||
<div className="section">{state.strings.account}</div>
|
||||
<div className="controls">
|
||||
<div className="switch">
|
||||
<div className="control">
|
||||
<Switch size="small" checked={state.searchable} onChange={enable => saveSearchable(enable)} />
|
||||
</div>
|
||||
<div className="switchLabel">{state.strings.registry}</div>
|
||||
</div>
|
||||
<div className="link" onClick={actions.setEditSeal}>
|
||||
<div className="control">
|
||||
<SettingOutlined />
|
||||
</div>
|
||||
<div className="label">{state.strings.sealedTopics}</div>
|
||||
</div>
|
||||
<div className="link" onClick={actions.setEditLogin}>
|
||||
<div className="control">
|
||||
<LockOutlined />
|
||||
</div>
|
||||
<div className="label">{state.strings.changeLogin}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="account">
|
||||
<div className="section">{state.strings.application}</div>
|
||||
<div className="controls">
|
||||
@ -94,28 +117,27 @@ export function AccountAccess() {
|
||||
options={state.languages}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="account">
|
||||
<div className="section">{state.strings.account}</div>
|
||||
<div className="controls">
|
||||
<div className="switch">
|
||||
<div className="control">
|
||||
<Switch size="small" checked={state.searchable} onChange={enable => saveSearchable(enable)} />
|
||||
</div>
|
||||
<div className="switchLabel">{state.strings.registry}</div>
|
||||
<div className="option">
|
||||
<div className="label">{state.strings.microphone}</div>
|
||||
<Select
|
||||
defaultValue={null}
|
||||
style={{ width: '60%' }}
|
||||
size="small"
|
||||
value={state.audioInput}
|
||||
onChange={actions.setAudio}
|
||||
options={[ { value: null, label: 'Default' }, ...state.audioInputs ]}
|
||||
/>
|
||||
</div>
|
||||
<div className="link" onClick={actions.setEditSeal}>
|
||||
<div className="control">
|
||||
<SettingOutlined />
|
||||
</div>
|
||||
<div className="label">{state.strings.sealedTopics}</div>
|
||||
</div>
|
||||
<div className="link" onClick={actions.setEditLogin}>
|
||||
<div className="control">
|
||||
<LockOutlined />
|
||||
</div>
|
||||
<div className="label">{state.strings.changeLogin}</div>
|
||||
<div className="option">
|
||||
<div className="label">{state.strings.camera}</div>
|
||||
<Select
|
||||
defaultValue={null}
|
||||
style={{ width: '60%' }}
|
||||
size="small"
|
||||
value={state.videoInput}
|
||||
onChange={actions.setVideo}
|
||||
options={[ { value: null, label: 'Default' }, ...state.videoInputs ]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -35,6 +35,7 @@ export const AccountAccessWrapper = styled.div`
|
||||
display: flex;
|
||||
padding-top: 8px;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.label {
|
||||
padding-right: 16px;
|
||||
|
@ -2,6 +2,7 @@ import { useRef, useState, useEffect, useContext } from 'react';
|
||||
import { AccountContext } from 'context/AccountContext';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { SettingsContext } from 'context/SettingsContext';
|
||||
import { RingContext } from 'context/RingContext';
|
||||
import { generateSeal, unlockSeal, updateSeal } from 'context/sealUtil';
|
||||
import { getUsername } from 'api/getUsername';
|
||||
export function useAccountAccess() {
|
||||
@ -34,6 +35,10 @@ export function useAccountAccess() {
|
||||
themes: [],
|
||||
language: null,
|
||||
languages: [],
|
||||
audioInput: null,
|
||||
audioInputs: [],
|
||||
videoInput: null,
|
||||
videoInputs: [],
|
||||
|
||||
seal: null,
|
||||
sealKey: null,
|
||||
@ -42,6 +47,7 @@ export function useAccountAccess() {
|
||||
const profile = useContext(ProfileContext);
|
||||
const account = useContext(AccountContext);
|
||||
const settings = useContext(SettingsContext);
|
||||
const ring = useContext(RingContext);
|
||||
const debounce = useRef(null);
|
||||
|
||||
const updateState = (value) => {
|
||||
@ -59,10 +65,21 @@ export function useAccountAccess() {
|
||||
}, [account.state]);
|
||||
|
||||
useEffect(() => {
|
||||
const { strings, menuStyle, timeFormat, dateFormat, theme, themes, language, languages } = settings.state;
|
||||
updateState({ strings, menuStyle, timeFormat, dateFormat, theme, themes, language, languages });
|
||||
const { audioInput, audioInputs, videoInput, videoInputs, strings, menuStyle, timeFormat, dateFormat, theme, themes, language, languages } = settings.state;
|
||||
updateState({ audioInput, audioInputs, videoInput, videoInputs, strings, menuStyle, timeFormat, dateFormat, theme, themes, language, languages });
|
||||
}, [settings.state]);
|
||||
|
||||
const showDevices = async () => {
|
||||
const audio = await ring.actions.getDevices('audio');
|
||||
const video = await ring.actions.getDevices('video');
|
||||
|
||||
console.log('devices', audio, video);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
showDevices();
|
||||
}, []);
|
||||
|
||||
const sealUnlock = async () => {
|
||||
const unlocked = unlockSeal(state.seal, state.sealUnlock);
|
||||
await account.actions.unlockSeal(unlocked);
|
||||
@ -113,6 +130,12 @@ export function useAccountAccess() {
|
||||
setLanguage: (language) => {
|
||||
settings.actions.setLanguage(language);
|
||||
},
|
||||
setAudio: (device) => {
|
||||
settings.actions.setAudioInput(device);
|
||||
},
|
||||
setVideo: (device) => {
|
||||
settings.actions.setVideoInput(device);
|
||||
},
|
||||
setEditSeal: () => {
|
||||
let sealMode;
|
||||
let sealEnabled = isEnabled();
|
||||
|
@ -9,7 +9,7 @@ export const SelectItemWrapper = styled.div`
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user