Initial commit
This commit is contained in:
191
pages/onboarding/onboarding1.vue
Normal file
191
pages/onboarding/onboarding1.vue
Normal file
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row text-center">
|
||||
<div class="col-12">
|
||||
<h1 class="h3 fw-bold mb-4">
|
||||
{{ t("How is your audio hardware connected?") }}
|
||||
</h1>
|
||||
<p class="text-muted mx-auto">
|
||||
{{ t('Onboarding-input') }}<br>
|
||||
{{ t('Onboarding-output') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-4">
|
||||
<div class="col-11">
|
||||
<form v-if="!loading">
|
||||
<div class="row justify-content-center mb-4">
|
||||
<div class="col-md-5 text-center">
|
||||
<label for="inputSelect" class="fw-semibold">{{ t('Input device:') }}</label>
|
||||
<p class="pt-0 mt-0 text-muted pb-2 mb-0" style="font-size: 14px;font-weight: 500">
|
||||
({{ t('select laptop or mobile device microphone') }})
|
||||
</p>
|
||||
<select id="inputSelect" v-model="selectedInput" class="form-select pt-1 mt-0 select-box" @change="checkIfSameDevice">
|
||||
<option v-for="(item,index) in audioInputDevices" :key="index" :value="index">
|
||||
{{ item.label || `Eingabegerät ${index + 1}` }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-center mb-4">
|
||||
<div class="col-md-5 text-center">
|
||||
<label for="outputSelect" class="fw-semibold">{{ t('Output device:') }}</label>
|
||||
<p class="pt-0 mt-0 text-muted pb-0 mb-0" style="font-size: 14px;font-weight: 500">
|
||||
{{ t('select headphones or headphone output') }}
|
||||
</p>
|
||||
<select id="outputSelect" v-model="selectedOutput" class="form-select pt-1 mt-0 select-box" @change="checkIfSameDevice">
|
||||
<option v-for="(item,index) in audioOutputDevices" :key="index" :value="index">
|
||||
{{ item.label || `Ausgabegerät ${index + 1}` }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-center pt-4">
|
||||
<div class="col-md-3 text-center" style="z-index: 1000000;">
|
||||
<button
|
||||
type="button"
|
||||
class="btn col-4 btn-primary-custom"
|
||||
:disabled="audioInputDevices.length === 0 || audioOutputDevices.length === 0"
|
||||
@click.prevent="saveDevices"
|
||||
>
|
||||
{{ t("Next") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div v-else class="text-center">
|
||||
<p>Lade Geräte...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapState, mapActions } from 'pinia'
|
||||
import { useUserStore } from '~/stores/user'
|
||||
|
||||
export default {
|
||||
emits: ['next-step'],
|
||||
setup () {
|
||||
const { t } = useI18n()
|
||||
const localePath = useLocalePath()
|
||||
|
||||
return {
|
||||
t,
|
||||
localePath
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: true,
|
||||
audioInputDevices: [],
|
||||
audioOutputDevices: [],
|
||||
selectedInput: null,
|
||||
selectedOutput: null,
|
||||
stream: null
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(useUserStore, ['audioInputDevice', 'audioOutputDevice'])
|
||||
|
||||
},
|
||||
async created () {
|
||||
try {
|
||||
// Zuerst Media-Zugriff einholen (sonst keine Labels)
|
||||
await this.getUserMedia()
|
||||
|
||||
const devices = await navigator.mediaDevices.enumerateDevices()
|
||||
|
||||
this.audioInputDevices = devices.filter(d => d.kind === 'audioinput')
|
||||
this.audioOutputDevices = devices.filter(d => d.kind === 'audiooutput')
|
||||
|
||||
// Setze Indexe basierend auf gespeicherten IDs
|
||||
this.selectedInput = this.audioInputDevices.findIndex(d => d.deviceId === this.audioInputDevice.deviceId)
|
||||
this.selectedOutput = this.audioOutputDevices.findIndex(d => d.deviceId === this.audioOutputDevice.deviceId)
|
||||
|
||||
// Fallback auf erstes Gerät
|
||||
if (this.selectedInput < 0) { this.selectedInput = 0 }
|
||||
if (this.selectedOutput < 0) { this.selectedOutput = 0 }
|
||||
|
||||
// Warnung, wenn gleiche Geräte gewählt sind
|
||||
if (this.checkIfSameDevice()) {
|
||||
this.$toast.warning(this.t('bluetoothWarning'), {
|
||||
duration: 6000,
|
||||
pauseOnHover: true,
|
||||
dismissible: true,
|
||||
queue: true,
|
||||
position: 'bottom-left'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
this.$toast.error(this.t('Could not access audio devices.'))
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useUserStore, ['saveInputdevice', 'saveOutputDevice']),
|
||||
|
||||
normalizeDeviceName (deviceName) {
|
||||
return deviceName
|
||||
.replace('Standard - ', '') // Remove 'Standard - '
|
||||
.replace(/ \(.*\)$/, '') // Remove any content in parentheses
|
||||
.trim()
|
||||
},
|
||||
checkIfSameDevice () {
|
||||
const input = this.audioInputDevices[this.selectedInput]
|
||||
const output = this.audioOutputDevices[this.selectedOutput]
|
||||
|
||||
if (!input?.label || !output?.label) { return false }
|
||||
|
||||
return this.normalizeDeviceName(input.label) === this.normalizeDeviceName(output.label)
|
||||
},
|
||||
saveDevices () {
|
||||
this.saveInputdevice(this.audioInputDevices[this.selectedInput])
|
||||
this.saveOutputDevice(this.audioOutputDevices[this.selectedOutput])
|
||||
this.$emit('next-step')
|
||||
},
|
||||
async getUserMedia () {
|
||||
try {
|
||||
return await navigator.mediaDevices.getUserMedia({ audio: true })
|
||||
} catch (error) {
|
||||
this.$logger('keine Mikrofon-Berechtigung erteilt.')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bar{
|
||||
background-color: #e9c046;
|
||||
}
|
||||
|
||||
.select-box{
|
||||
border: 2px solid #e9c046;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.select-box:focus{
|
||||
border: 2px solid #e9c046;
|
||||
box-shadow: none;
|
||||
|
||||
}
|
||||
|
||||
.btn-primary-custom {
|
||||
background-color: #e9c046;
|
||||
border-color: #e9c046;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-primary-custom:hover, .btn-primary-custom:focus{
|
||||
background-color: transparent;
|
||||
border-color: #e9c046;
|
||||
color: #e9c046;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user