Skip to content

Commit

Permalink
Merge pull request #6613 from TheThingsNetwork/fix/camera-switch-mobile
Browse files Browse the repository at this point in the history
Fix switch camera
  • Loading branch information
ryaplots authored Oct 19, 2023
2 parents 179cc39 + cfd9cf7 commit c69cb8c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
1 change: 1 addition & 0 deletions pkg/webui/components/modal/modal.styl
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
margin-bottom: $cs.s
flex-direction: row
align-items: stretch
gap: 1rem

button:not(:last-child)
margin-right: 0
Expand Down
57 changes: 34 additions & 23 deletions pkg/webui/components/qr/input/video/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const Video = props => {
const [stream, setStream] = useState(undefined)
const [devices, setDevices] = useState([])
const [cameras, setCameras] = useState([])
const isMobile = window.innerWidth <= 768
const [videoMode, setVideoMode] = useState({})

const getDevices = useCallback(async () => {
if (!devices.length) {
Expand All @@ -59,6 +59,7 @@ const Video = props => {
: { deviceId: rearCamera.deviceId }
: { facingMode: 'environment' }

setVideoMode(videoMode)
try {
const userStream = await navigator.mediaDevices.getUserMedia({
video: videoMode ? { ...videoMode } : { facingMode: 'environment' },
Expand All @@ -76,30 +77,38 @@ const Video = props => {
}, [devices, setCapture, setError, stream])

const switchStream = useCallback(async () => {
if (stream === { facingMode: 'environment' }) {
const ua = navigator.userAgent.toLowerCase()
if (ua.indexOf('safari') !== -1 && ua.indexOf('chrome') === -1) {
const userStream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: {
exact: videoMode.facingMode.exact === 'environment' ? 'user' : 'environment',
},
},
})
setStream(userStream)
} else if (videoMode.facingMode === 'environment') {
const userStream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'user' },
})
setStream(userStream)
} else if (stream === { facingMode: 'user' }) {
} else if (videoMode.facingMode === 'user') {
const userStream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' },
})
setStream(userStream)
} else if ('deviceId' in stream) {
const indexOfCurrentDevice = cameras.findIndex(camera => camera.deviceId === stream.deviceId)
} else if ('deviceId' in videoMode) {
let indexOfCurrentDevice = cameras.findIndex(camera => camera.deviceId === videoMode.deviceId)
// The first item will be taken from the beginning of the array after the last item.
const nextIndex = ++indexOfCurrentDevice % cameras.length
const device =
cameras.length === 2
? cameras.find((_, i) => i !== indexOfCurrentDevice)
: cameras[nextIndex]
const device = cameras[nextIndex]
setVideoMode({ deviceId: device.deviceId })
const userStream = await navigator.mediaDevices.getUserMedia({
video: { deviceId: device.deviceId },
})
setStream(userStream)
}
}, [cameras, stream])
}, [cameras, videoMode])

useEffect(() => {
getDevices()
Expand Down Expand Up @@ -135,23 +144,25 @@ const Video = props => {
}
}, [devices, handleVideoFrame, stream, videoRef])

return devices.length && stream ? (
return (
<>
<video
autoPlay
playsInline
ref={videoRef}
className={style.video}
data-test-id="webcam-feed"
/>
{cameras.length > 1 && isMobile && (
{cameras.length > 1 && (
<Button icon="switch_camera" message={m.switchCamera} onClick={switchStream} />
)}
{devices.length && stream ? (
<video
autoPlay
playsInline
ref={videoRef}
className={style.video}
data-test-id="webcam-feed"
/>
) : (
<Spinner center>
<Message className={style.msg} content={m.fetchingCamera} />
</Spinner>
)}
</>
) : (
<Spinner center>
<Message className={style.msg} content={m.fetchingCamera} />
</Spinner>
)
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/webui/components/qr/qr.styl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
align-items: center
justify-content: center
position: relative
+media-query($bp.s)
background: none
align-items: start

.capture
background: $c-backdrop
Expand Down

0 comments on commit c69cb8c

Please sign in to comment.