2022-05-04 17:09:48 +01:00
/ *
2023-01-03 16:55:26 +00:00
Copyright 2022 New Vector Ltd
2022-05-04 17:09:48 +01:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2022-02-04 16:55:57 -08:00
import React from "react" ;
2022-06-06 22:42:48 +02:00
import { Item } from "@react-stately/collections" ;
2022-10-10 09:19:10 -04:00
import { useTranslation } from "react-i18next" ;
2022-06-06 22:42:48 +02:00
2022-01-05 16:54:13 -08:00
import { Modal } from "../Modal" ;
2021-12-06 17:34:10 -08:00
import styles from "./SettingsModal.module.css" ;
2022-01-21 15:43:03 -08:00
import { TabContainer , TabItem } from "../tabs/Tabs" ;
2022-01-05 16:54:13 -08:00
import { ReactComponent as AudioIcon } from "../icons/Audio.svg" ;
import { ReactComponent as VideoIcon } from "../icons/Video.svg" ;
import { ReactComponent as DeveloperIcon } from "../icons/Developer.svg" ;
2022-11-05 11:13:56 +01:00
import { ReactComponent as OverflowIcon } from "../icons/Overflow.svg" ;
2022-01-05 17:27:01 -08:00
import { SelectInput } from "../input/SelectInput" ;
2022-06-08 17:22:46 +02:00
import { useMediaHandler } from "./useMediaHandler" ;
2022-11-04 13:07:14 +01:00
import {
2022-11-14 10:21:24 +00:00
useKeyboardShortcuts ,
2022-11-04 13:07:14 +01:00
useSpatialAudio ,
useShowInspector ,
useOptInAnalytics ,
2022-12-16 17:12:17 +00:00
canEnableSpatialAudio ,
2022-11-04 13:07:14 +01:00
} from "./useSetting" ;
2022-02-04 16:55:57 -08:00
import { FieldRow , InputField } from "../input/Input" ;
2022-02-01 15:11:06 -08:00
import { Button } from "../button" ;
2022-04-07 14:22:36 -07:00
import { useDownloadDebugLog } from "./submit-rageshake" ;
2022-02-16 11:29:43 -08:00
import { Body } from "../typography/Typography" ;
2021-12-06 17:34:10 -08:00
2022-06-06 22:42:48 +02:00
interface Props {
2022-08-02 00:46:16 +02:00
isOpen : boolean ;
onClose : ( ) = > void ;
2022-06-06 22:42:48 +02:00
}
export const SettingsModal = ( props : Props ) = > {
2022-10-10 09:19:10 -04:00
const { t } = useTranslation ( ) ;
2021-12-06 17:34:10 -08:00
const {
audioInput ,
audioInputs ,
setAudioInput ,
videoInput ,
videoInputs ,
setVideoInput ,
2022-02-22 18:32:51 -08:00
audioOutput ,
audioOutputs ,
setAudioOutput ,
} = useMediaHandler ( ) ;
2022-06-06 22:42:48 +02:00
2022-05-31 10:43:05 -04:00
const [ spatialAudio , setSpatialAudio ] = useSpatialAudio ( ) ;
const [ showInspector , setShowInspector ] = useShowInspector ( ) ;
2022-11-04 13:07:14 +01:00
const [ optInAnalytics , setOptInAnalytics ] = useOptInAnalytics ( ) ;
2022-11-14 10:21:24 +00:00
const [ keyboardShortcuts , setKeyboardShortcuts ] = useKeyboardShortcuts ( ) ;
2021-12-06 17:34:10 -08:00
2022-02-04 16:55:57 -08:00
const downloadDebugLog = useDownloadDebugLog ( ) ;
2022-02-01 15:11:06 -08:00
2021-12-06 17:34:10 -08:00
return (
< Modal
2022-10-10 09:19:10 -04:00
title = { t ( "Settings" ) }
2021-12-06 17:34:10 -08:00
isDismissable
2021-12-10 10:54:18 -08:00
mobileFullScreen
2021-12-06 17:34:10 -08:00
className = { styles . settingsModal }
2022-05-31 10:43:05 -04:00
{ . . . props }
2021-12-06 17:34:10 -08:00
>
< TabContainer className = { styles . tabContainer } >
< TabItem
title = {
< >
< AudioIcon width = { 16 } height = { 16 } / >
2022-10-10 09:19:10 -04:00
< span > { t ( "Audio" ) } < / span >
2021-12-06 17:34:10 -08:00
< / >
}
>
< SelectInput
2022-10-10 09:19:10 -04:00
label = { t ( "Microphone" ) }
2021-12-06 17:34:10 -08:00
selectedKey = { audioInput }
onSelectionChange = { setAudioInput }
>
2022-07-07 12:10:08 +02:00
{ audioInputs . map ( ( { deviceId , label } , index ) = > (
2022-07-07 10:31:44 +02:00
< Item key = { deviceId } >
{ ! ! label && label . trim ( ) . length > 0
? label
2022-10-10 09:19:10 -04:00
: t ( "Microphone {{n}}" , { n : index + 1 } ) }
2022-07-07 10:31:44 +02:00
< / Item >
2021-12-06 17:34:10 -08:00
) ) }
< / SelectInput >
2022-02-22 18:32:51 -08:00
{ audioOutputs . length > 0 && (
< SelectInput
2022-10-10 09:19:10 -04:00
label = { t ( "Speaker" ) }
2022-02-22 18:32:51 -08:00
selectedKey = { audioOutput }
onSelectionChange = { setAudioOutput }
>
2022-07-07 12:10:08 +02:00
{ audioOutputs . map ( ( { deviceId , label } , index ) = > (
2022-07-07 10:31:44 +02:00
< Item key = { deviceId } >
{ ! ! label && label . trim ( ) . length > 0
? label
2022-10-10 09:19:10 -04:00
: t ( "Speaker {{n}}" , { n : index + 1 } ) }
2022-07-07 10:31:44 +02:00
< / Item >
2022-02-22 18:32:51 -08:00
) ) }
< / SelectInput >
) }
2022-05-31 10:43:05 -04:00
< FieldRow >
< InputField
id = "spatialAudio"
2022-10-10 09:19:10 -04:00
label = { t ( "Spatial audio" ) }
2022-05-31 10:43:05 -04:00
type = "checkbox"
checked = { spatialAudio }
2022-12-16 17:12:17 +00:00
disabled = { ! canEnableSpatialAudio ( ) }
description = {
canEnableSpatialAudio ( )
? t (
"This will make a speaker's audio seem as if it is coming from where their tile is positioned on screen. (Experimental feature: this may impact the stability of audio.)"
)
: t ( "This feature is only supported on Firefox." )
}
2022-06-11 14:28:54 +02:00
onChange = { ( event : React.ChangeEvent < HTMLInputElement > ) = >
setSpatialAudio ( event . target . checked )
}
2022-05-31 10:43:05 -04:00
/ >
< / FieldRow >
2021-12-06 17:34:10 -08:00
< / TabItem >
< TabItem
title = {
< >
< VideoIcon width = { 16 } height = { 16 } / >
2022-10-10 09:19:10 -04:00
< span > { t ( "Video" ) } < / span >
2021-12-06 17:34:10 -08:00
< / >
}
>
< SelectInput
2022-10-10 09:19:10 -04:00
label = { t ( "Camera" ) }
2021-12-06 17:34:10 -08:00
selectedKey = { videoInput }
onSelectionChange = { setVideoInput }
>
2022-07-07 12:10:08 +02:00
{ videoInputs . map ( ( { deviceId , label } , index ) = > (
2022-07-07 10:31:44 +02:00
< Item key = { deviceId } >
2022-07-07 12:10:08 +02:00
{ ! ! label && label . trim ( ) . length > 0
? label
2022-10-10 09:19:10 -04:00
: t ( "Camera {{n}}" , { n : index + 1 } ) }
2022-07-07 10:31:44 +02:00
< / Item >
2021-12-06 17:34:10 -08:00
) ) }
< / SelectInput >
< / TabItem >
< TabItem
title = {
2022-11-05 11:13:56 +01:00
< >
< OverflowIcon width = { 16 } height = { 16 } / >
< span > { t ( "Advanced" ) } < / span >
< / >
}
>
< FieldRow >
< InputField
id = "optInAnalytics"
label = { t ( "Allow analytics" ) }
type = "checkbox"
checked = { optInAnalytics }
description = { t (
2022-11-08 07:53:17 -05:00
"This will send anonymised data (such as the duration of a call and the number of participants) to the Element Call team to help us optimise the application based on how it is used."
2022-11-05 11:13:56 +01:00
) }
onChange = { ( event : React.ChangeEvent < HTMLInputElement > ) = >
setOptInAnalytics ( event . target . checked )
}
/ >
< / FieldRow >
2022-11-14 10:21:24 +00:00
< FieldRow >
< InputField
id = "keyboardShortcuts"
2022-11-14 20:57:36 +00:00
label = { t ( "Single-key keyboard shortcuts" ) }
2022-11-14 10:21:24 +00:00
type = "checkbox"
checked = { keyboardShortcuts }
2022-11-14 11:29:42 +00:00
description = { t (
2022-11-14 20:57:36 +00:00
"Whether to enable single-key keyboard shortcuts, e.g. 'm' to mute/unmute the mic."
2022-11-14 11:29:42 +00:00
) }
2022-11-14 10:21:24 +00:00
onChange = { ( event : React.ChangeEvent < HTMLInputElement > ) = >
setKeyboardShortcuts ( event . target . checked )
}
/ >
< / FieldRow >
2022-11-05 11:13:56 +01:00
< / TabItem >
< TabItem
title = {
2021-12-06 17:34:10 -08:00
< >
< DeveloperIcon width = { 16 } height = { 16 } / >
2022-10-10 09:19:10 -04:00
< span > { t ( "Developer" ) } < / span >
2021-12-06 17:34:10 -08:00
< / >
}
>
2022-02-16 11:29:43 -08:00
< FieldRow >
< Body className = { styles . fieldRowText } >
2022-10-10 09:19:10 -04:00
{ t ( "Version: {{version}}" , {
version : import.meta.env.VITE_APP_VERSION || "dev" ,
} ) }
2022-02-16 11:29:43 -08:00
< / Body >
< / FieldRow >
2021-12-06 17:34:10 -08:00
< FieldRow >
< InputField
id = "showInspector"
name = "inspector"
2022-10-10 09:19:10 -04:00
label = { t ( "Show call inspector" ) }
2021-12-06 17:34:10 -08:00
type = "checkbox"
checked = { showInspector }
2022-06-11 14:28:54 +02:00
onChange = { ( e : React.ChangeEvent < HTMLInputElement > ) = >
setShowInspector ( e . target . checked )
}
2021-12-06 17:34:10 -08:00
/ >
< / FieldRow >
2022-02-01 15:11:06 -08:00
< FieldRow >
2022-10-10 09:19:10 -04:00
< Button onPress = { downloadDebugLog } >
{ t ( "Download debug logs" ) }
< / Button >
2022-02-01 15:11:06 -08:00
< / FieldRow >
2021-12-06 17:34:10 -08:00
< / TabItem >
< / TabContainer >
< / Modal >
) ;
2022-05-31 10:43:05 -04:00
} ;