♻️(frontend) encapsulate transcript language logic in a hook

Provide a clear interface to handle transcription language selection and
behavior, reducing code duplication across the codebase.
This commit is contained in:
lebaudantoine
2025-12-31 19:43:33 +01:00
committed by aleb_the_flash
parent f7d463f380
commit 398ef1ae8a
6 changed files with 70 additions and 52 deletions

View File

@@ -13,11 +13,7 @@ import {
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { ConnectionState, RoomEvent } from 'livekit-client' import { ConnectionState, RoomEvent } from 'livekit-client'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import { RecordingStatus, recordingStore } from '@/stores/recording'
RecordingLanguage,
RecordingStatus,
recordingStore,
} from '@/stores/recording'
import { import {
NotificationType, NotificationType,
@@ -32,6 +28,7 @@ import { FeatureFlags } from '@/features/analytics/enums'
import { NoAccessView } from './NoAccessView' import { NoAccessView } from './NoAccessView'
import { HStack, VStack } from '@/styled-system/jsx' import { HStack, VStack } from '@/styled-system/jsx'
import { Checkbox } from '@/primitives/Checkbox' import { Checkbox } from '@/primitives/Checkbox'
import { useTranscriptionLanguage } from '@/features/settings'
export const ScreenRecordingSidePanel = () => { export const ScreenRecordingSidePanel = () => {
const { data } = useConfig() const { data } = useConfig()
@@ -51,6 +48,8 @@ export const ScreenRecordingSidePanel = () => {
) )
const { notifyParticipants } = useNotifyParticipants() const { notifyParticipants } = useNotifyParticipants()
const { selectedLanguageKey, isLanguageSetToAuto } =
useTranscriptionLanguage()
const roomId = useRoomId() const roomId = useRoomId()
@@ -109,8 +108,8 @@ export const ScreenRecordingSidePanel = () => {
) )
} else { } else {
const recordingOptions = { const recordingOptions = {
...(recordingSnap.language != RecordingLanguage.AUTOMATIC && { ...(!isLanguageSetToAuto && {
language: recordingSnap.language, language: selectedLanguageKey,
}), }),
...(includeTranscript && { transcribe: true }), ...(includeTranscript && { transcribe: true }),
} }

View File

@@ -14,11 +14,7 @@ import {
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { ConnectionState, RoomEvent } from 'livekit-client' import { ConnectionState, RoomEvent } from 'livekit-client'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import { RecordingStatus } from '@store/recording'
RecordingLanguage,
RecordingStatus,
recordingStore,
} from '@/stores/recording'
import { FeatureFlags } from '@/features/analytics/enums' import { FeatureFlags } from '@/features/analytics/enums'
import { import {
NotificationType, NotificationType,
@@ -35,7 +31,7 @@ import { Checkbox } from '@/primitives/Checkbox.tsx'
import { import {
useSettingsDialog, useSettingsDialog,
SettingsDialogExtendedKey, SettingsDialogExtendedKey,
useTranscriptionLanguageOptions, useTranscriptionLanguage,
} from '@/features/settings' } from '@/features/settings'
import { NoAccessView } from './NoAccessView' import { NoAccessView } from './NoAccessView'
@@ -52,7 +48,8 @@ export const TranscriptSidePanel = () => {
const recordingSnap = useSnapshot(recordingStore) const recordingSnap = useSnapshot(recordingStore)
const { notifyParticipants } = useNotifyParticipants() const { notifyParticipants } = useNotifyParticipants()
const languageOptions = useTranscriptionLanguageOptions() const { selectedLanguageKey, selectedLanguageLabel, isLanguageSetToAuto } =
useTranscriptionLanguage()
const { openSettingsDialog } = useSettingsDialog() const { openSettingsDialog } = useSettingsDialog()
@@ -125,8 +122,9 @@ export const TranscriptSidePanel = () => {
: RecordingMode.Transcript : RecordingMode.Transcript
const recordingOptions = { const recordingOptions = {
...(recordingSnap.language != RecordingLanguage.AUTOMATIC && { ...(!isLanguageSetToAuto && {
language: recordingSnap.language, language: selectedLanguageKey,
}),
}), }),
...(includeScreenRecording && { transcribe: true }), ...(includeScreenRecording && { transcribe: true }),
} }
@@ -327,11 +325,7 @@ export const TranscriptSidePanel = () => {
openSettingsDialog(SettingsDialogExtendedKey.TRANSCRIPTION) openSettingsDialog(SettingsDialogExtendedKey.TRANSCRIPTION)
} }
> >
{ {selectedLanguageLabel}
languageOptions.find(
(option) => option.key == recordingSnap.language
)?.label
}
</Button> </Button>
</Text> </Text>
</div> </div>

View File

@@ -3,7 +3,7 @@ import { Field, H } from '@/primitives'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { RecordingLanguage, recordingStore } from '@/stores/recording' import { RecordingLanguage, recordingStore } from '@/stores/recording'
import { useSnapshot } from 'valtio' import { useSnapshot } from 'valtio'
import { useTranscriptionLanguageOptions } from '../../hook/useTranscriptionLanguageOptions' import { useTranscriptionLanguage } from '@/features/settings'
export type TranscriptionTabProps = Pick<TabPanelProps, 'id'> export type TranscriptionTabProps = Pick<TabPanelProps, 'id'>
@@ -11,7 +11,7 @@ export const TranscriptionTab = ({ id }: TranscriptionTabProps) => {
const { t } = useTranslation('settings', { keyPrefix: 'transcription' }) const { t } = useTranslation('settings', { keyPrefix: 'transcription' })
const recordingSnap = useSnapshot(recordingStore) const recordingSnap = useSnapshot(recordingStore)
const languageOptions = useTranscriptionLanguageOptions() const { languageOptions } = useTranscriptionLanguage()
return ( return (
<TabPanel padding={'md'} flex id={id}> <TabPanel padding={'md'} flex id={id}>

View File

@@ -0,0 +1,53 @@
import { useMemo } from 'react'
import { RecordingLanguage, recordingStore } from '@/stores/recording'
import { useTranslation } from 'react-i18next'
import { useSnapshot } from 'valtio/index'
export const useTranscriptionLanguage = () => {
const { t } = useTranslation('settings', { keyPrefix: 'transcription' })
const recordingSnap = useSnapshot(recordingStore)
const languages = useMemo(
() => [
{
key: RecordingLanguage.FRENCH,
label: t('language.options.french'),
},
{
key: RecordingLanguage.ENGLISH,
label: t('language.options.english'),
},
{
key: RecordingLanguage.AUTOMATIC,
label: t('language.options.auto'),
},
],
[t]
)
const languageOptions = useMemo(() => {
return languages.map((i) => ({
key: i.key,
value: i.key,
label: i.label,
}))
}, [languages])
const { selectedLanguageKey, selectedLanguageLabel } = useMemo(() => {
const selectedLanguageLabel = languages.find(
(option) => option.key === recordingSnap.language
)?.label
const selectedLanguageKey = recordingSnap.language
return { selectedLanguageKey, selectedLanguageLabel }
}, [recordingSnap.language, languages])
return {
languageOptions,
selectedLanguageKey,
selectedLanguageLabel,
isLanguageSetToAuto: selectedLanguageKey === RecordingLanguage.AUTOMATIC,
}
}

View File

@@ -1,28 +0,0 @@
import { useMemo } from 'react'
import { RecordingLanguage } from '@/stores/recording'
import { useTranslation } from 'react-i18next'
export const useTranscriptionLanguageOptions = () => {
const { t } = useTranslation('settings', { keyPrefix: 'transcription' })
return useMemo(
() => [
{
key: RecordingLanguage.FRENCH,
value: RecordingLanguage.FRENCH,
label: t('language.options.french'),
},
{
key: RecordingLanguage.ENGLISH,
value: RecordingLanguage.ENGLISH,
label: t('language.options.english'),
},
{
key: RecordingLanguage.AUTOMATIC,
value: RecordingLanguage.AUTOMATIC,
label: t('language.options.auto'),
},
],
[t]
)
}

View File

@@ -1,7 +1,7 @@
export { SettingsButton } from './components/SettingsButton' export { SettingsButton } from './components/SettingsButton'
export { SettingsDialog } from './components/SettingsDialog' export { SettingsDialog } from './components/SettingsDialog'
export { useTranscriptionLanguageOptions } from './hook/useTranscriptionLanguageOptions' export { useTranscriptionLanguage } from './hook/useTranscriptionLanguage'
export { useSettingsDialog } from './hook/useSettingsDialog' export { useSettingsDialog } from './hook/useSettingsDialog'
export { SettingsDialogExtendedKey } from './type.ts' export { SettingsDialogExtendedKey } from './type.ts'