user preferences
All checks were successful
Deploy / deploy (push) Successful in 36s

This commit is contained in:
2025-12-25 22:50:56 +06:00
parent 22c5fafb11
commit bf38267c37
21 changed files with 359 additions and 102 deletions

View File

@@ -8,6 +8,8 @@ export const useApp = createGlobalState(() => {
const mediasoup = useMediasoup()
const toast = useToast()
const ready = ref(false)
const inputMuted = ref(false)
const outputMuted = ref(false)
@@ -15,8 +17,38 @@ export const useApp = createGlobalState(() => {
const isTauri = computed(() => '__TAURI_INTERNALS__' in window)
const commitSha = __COMMIT_SHA__
const version = computedAsync(() => isTauri.value ? getVersion() : 'web', '-')
watch(inputMuted, async (inputMuted) => {
if (inputMuted) {
await mediasoup.pauseProducer('microphone')
}
else {
if (outputMuted.value) {
outputMuted.value = false
}
await mediasoup.resumeProducer('microphone')
}
const toastText = inputMuted ? 'Microphone muted' : 'Microphone activated'
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
})
watch(outputMuted, (outputMuted) => {
if (outputMuted) {
previousInputMuted.value = inputMuted.value
muteInput()
}
else {
inputMuted.value = previousInputMuted.value
}
const toastText = outputMuted ? 'Sound muted' : 'Sound resumed'
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
})
function muteInput() {
inputMuted.value = true
}
@@ -47,35 +79,8 @@ export const useApp = createGlobalState(() => {
muteOutput()
}
watch(inputMuted, async (inputMuted) => {
if (inputMuted) {
await mediasoup.pauseProducer('microphone')
}
else {
if (outputMuted.value) {
outputMuted.value = false
}
await mediasoup.resumeProducer('microphone')
}
const toastText = inputMuted ? 'Microphone muted' : 'Microphone activated'
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
})
watch(outputMuted, (outputMuted) => {
if (outputMuted) {
previousInputMuted.value = inputMuted.value
muteInput()
}
else {
inputMuted.value = previousInputMuted.value
}
const toastText = outputMuted ? 'Sound muted' : 'Sound resumed'
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
})
return {
ready,
clients,
inputMuted,
muteInput,
@@ -87,5 +92,6 @@ export const useApp = createGlobalState(() => {
toggleOutput,
version,
isTauri,
commitSha,
}
})

View File

@@ -1,6 +1,15 @@
import { createGlobalState, useDevicesList, useLocalStorage } from '@vueuse/core'
import chadApi from '#shared/chad-api'
import { createGlobalState, useDevicesList, useLocalStorage, watchDebounced } from '@vueuse/core'
export interface SyncedPreferences {
toggleInputHotkey: string
toggleOutputHotkey: string
volumes: Record<Client['id'], number>
}
export const usePreferences = createGlobalState(() => {
const synced = ref(false)
const inputDeviceId = useLocalStorage<MediaDeviceInfo['deviceId']>('INPUT_DEVICE_ID', 'default')
const outputDeviceId = useLocalStorage<MediaDeviceInfo['deviceId']>('OUTPUT_DEVICE_ID', 'default')
@@ -8,6 +17,9 @@ export const usePreferences = createGlobalState(() => {
const noiseSuppression = useLocalStorage('NOISE_SUPPRESSION', true)
const echoCancellation = useLocalStorage('ECHO_CANCELLATION', true)
const toggleInputHotkey = ref<SyncedPreferences['toggleInputHotkey']>('')
const toggleOutputHotkey = ref<SyncedPreferences['toggleOutputHotkey']>('')
const {
ensurePermissions,
permissionGranted,
@@ -24,12 +36,35 @@ export const usePreferences = createGlobalState(() => {
return audioOutputs.value.some(device => device.deviceId === outputDeviceId.value)
})
watchDebounced(
[toggleInputHotkey, toggleOutputHotkey],
async ([toggleInputHotkey, toggleOutputHotkey]) => {
try {
await chadApi(
'/preferences',
{
method: 'PATCH',
body: {
toggleInputHotkey,
toggleOutputHotkey,
},
},
)
}
catch {}
},
{ debounce: 1000 },
)
return {
synced,
inputDeviceId,
outputDeviceId,
autoGainControl,
noiseSuppression,
echoCancellation,
toggleInputHotkey,
toggleOutputHotkey,
inputDeviceExist,
outputDeviceExist,
videoInputs: computed(() => JSON.parse(JSON.stringify(videoInputs.value))),