Skip to content

Commit

Permalink
fix(sounds): request audio permissions only once when opening NcSelect
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
  • Loading branch information
Antreesy committed Jul 24, 2024
1 parent ae10fd5 commit f5fc8ce
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/services/webNotificationsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const playNotificationSound = (notification) => {
sound.play()

Check failure on line 71 in src/services/webNotificationsService.js

View workflow job for this annotation

GitHub Actions / NPM lint

Trailing spaces not allowed
const secondarySpeakerEnabled = BrowserStorage.getItem('secondary_speaker') === 'true'
const secondaryDeviceId = BrowserStorage.getItem('secondary_speaker_device_id')
const secondaryDeviceId = JSON.parse(BrowserStorage.getItem('secondary_speaker_device'))?.id ?? null
// Play only if secondary device is enabled, selected and different from primary device
if (secondarySpeakerEnabled && secondaryDeviceId && primaryDeviceId !== secondaryDeviceId) {
const soundDuped = new Howl(howlPayload)
Expand Down
59 changes: 34 additions & 25 deletions src/views/UserSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
:aria-label-combobox="t('notifications', 'Select a device')"
:clearable="false"
:placeholder="t('notifications', 'Select a device')"
:disabled="devices.length <= 1"
@open="initializeDevices"
@input="updateLocalSettings"/>

Check failure on line 54 in src/views/UserSettings.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected a space before '/>', but not found
</template>
</NcSettingsSection>
Expand Down Expand Up @@ -82,6 +82,7 @@ const batchtime_options = [
{ text: t('notifications', '1 day'), value: EmailFrequency.EMAIL_SEND_DAILY },
{ text: t('notifications', '1 week'), value: EmailFrequency.EMAIL_SEND_WEEKLY },
]
const empty_device_option = { id: null, label: t('notifications', 'None') }

Check failure on line 85 in src/views/UserSettings.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Identifier 'empty_device_option' is not in camel case
const parser = new UAParser()
const browser = parser.getBrowser()
const isSafari = browser.name === 'Safari' || browser.name === 'Mobile Safari'
Expand All @@ -98,30 +99,10 @@ export default {
const config = reactive(loadState('notifications', 'config'))
const storage = reactive({
secondary_speaker: BrowserStorage.getItem('secondary_speaker') === 'true',
secondary_speaker_device: null,
secondary_speaker_device: JSON.parse(BrowserStorage.getItem('secondary_speaker_device')) ?? empty_device_option,

Check failure on line 102 in src/views/UserSettings.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Identifier 'empty_device_option' is not in camel case
})
const devices = ref([])
onBeforeMount(async () => {
const isAudioSupported = !isSafari && navigator?.mediaDevices?.getUserMedia && navigator?.mediaDevices?.enumerateDevices
if (!isAudioSupported) {
return
}
// Request permissions to get audio devices
await navigator.mediaDevices.getUserMedia({ audio: true })
// Enumerate devices and populate NcSelect options
devices.value = (await navigator.mediaDevices.enumerateDevices() ?? [])
.filter(device => device.kind === 'audiooutput')
.map(device => ({
id: device.deviceId,
label: device.label ? device.label : device.fallbackLabel,
}))
const id = BrowserStorage.getItem('secondary_speaker_device_id')
storage.secondary_speaker_device = devices.value.find(device => device.id === id) ?? null
})
return {
batchtime_options,

Check failure on line 107 in src/views/UserSettings.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Identifier 'batchtime_options' is not in camel case
isSafari,
Expand Down Expand Up @@ -149,17 +130,45 @@ export default {
updateLocalSettings() {
try {
BrowserStorage.setItem('secondary_speaker', this.storage.secondary_speaker)
if (this.storage.secondary_speaker && this.storage.secondary_speaker_device) {
BrowserStorage.setItem('secondary_speaker_device_id', this.storage.secondary_speaker_device.id)
if (this.storage.secondary_speaker && this.storage.secondary_speaker_device.id) {
BrowserStorage.setItem('secondary_speaker_device', JSON.stringify(this.storage.secondary_speaker_device))
} else {
BrowserStorage.removeItem('secondary_speaker_device_id')
BrowserStorage.removeItem('secondary_speaker_device')
}
showSuccess(t('notifications', 'Your settings have been updated.'))
} catch (error) {
showError(t('notifications', 'An error occurred while updating your settings.'))
console.error(error)
}
},
async initializeDevices() {
const isAudioSupported = !isSafari && navigator?.mediaDevices?.getUserMedia && navigator?.mediaDevices?.enumerateDevices
if (!isAudioSupported || this.devices.length > 0) {
return
}
let stream = null
try {
// Request permissions to get audio devices
stream = await navigator.mediaDevices.getUserMedia({ audio: true })
// Enumerate devices and populate NcSelect options
this.devices = (await navigator.mediaDevices.enumerateDevices() ?? [])
.filter(device => device.kind === 'audiooutput')

Check failure on line 157 in src/views/UserSettings.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected indentation of 5 tabs but found 4
.map(device => ({

Check failure on line 158 in src/views/UserSettings.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected indentation of 5 tabs but found 4
id: device.deviceId,
label: device.label ? device.label : device.fallbackLabel,
}))
.concat([empty_device_option])
} catch(error) {
showError(t('notifications', 'An error occurred while updating your settings.'))
console.error('Error while requesting or initializing audio devices: ', error)
} finally {
if (stream) {
stream.getTracks().forEach(track => track.stop())
}
}
},
},
}
Expand Down

0 comments on commit f5fc8ce

Please sign in to comment.