diff --git a/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx b/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx
index 4c646114..64148508 100644
--- a/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx
+++ b/src/frontend/src/features/settings/components/SettingsDialogExtended.tsx
@@ -16,6 +16,7 @@ import { NotificationsTab } from './tabs/NotificationsTab'
import { GeneralTab } from './tabs/GeneralTab'
import { AudioTab } from './tabs/AudioTab'
import { VideoTab } from './tabs/VideoTab'
+import { TranscriptionTab } from './tabs/TranscriptionTab'
import { useRef } from 'react'
import { useMediaQuery } from '@/features/rooms/livekit/hooks/useMediaQuery'
import { SettingsDialogExtendedKey } from '@/features/settings/type'
@@ -100,6 +101,11 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
{isWideScreen &&
t(`tabs.${SettingsDialogExtendedKey.NOTIFICATIONS}`)}
+
+ speech_to_text
+ {isWideScreen &&
+ t(`tabs.${SettingsDialogExtendedKey.TRANSCRIPTION}`)}
+
@@ -111,6 +117,8 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
+ {/* Transcription tab won't be accessible if the tab is not active in the tab list */}
+
diff --git a/src/frontend/src/features/settings/components/tabs/TranscriptionTab.tsx b/src/frontend/src/features/settings/components/tabs/TranscriptionTab.tsx
new file mode 100644
index 00000000..3e859b0a
--- /dev/null
+++ b/src/frontend/src/features/settings/components/tabs/TranscriptionTab.tsx
@@ -0,0 +1,30 @@
+import { TabPanel, TabPanelProps } from '@/primitives/Tabs'
+import { Field, H } from '@/primitives'
+import { useTranslation } from 'react-i18next'
+import { RecordingLanguage, recordingStore } from '@/stores/recording'
+import { useSnapshot } from 'valtio'
+import { useTranscriptionLanguageOptions } from '../../hook/useTranscriptionLanguageOptions'
+
+export type TranscriptionTabProps = Pick
+
+export const TranscriptionTab = ({ id }: TranscriptionTabProps) => {
+ const { t } = useTranslation('settings', { keyPrefix: 'transcription' })
+ const recordingSnap = useSnapshot(recordingStore)
+
+ const languageOptions = useTranscriptionLanguageOptions()
+
+ return (
+
+ {t('heading')}
+ {
+ recordingStore.language = lang as RecordingLanguage
+ }}
+ />
+
+ )
+}
diff --git a/src/frontend/src/features/settings/hook/useTranscriptionLanguageOptions.ts b/src/frontend/src/features/settings/hook/useTranscriptionLanguageOptions.ts
new file mode 100644
index 00000000..f0dfc336
--- /dev/null
+++ b/src/frontend/src/features/settings/hook/useTranscriptionLanguageOptions.ts
@@ -0,0 +1,28 @@
+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]
+ )
+}
diff --git a/src/frontend/src/features/settings/index.ts b/src/frontend/src/features/settings/index.ts
index 077df744..1c198824 100644
--- a/src/frontend/src/features/settings/index.ts
+++ b/src/frontend/src/features/settings/index.ts
@@ -1,2 +1,7 @@
export { SettingsButton } from './components/SettingsButton'
export { SettingsDialog } from './components/SettingsDialog'
+
+export { useTranscriptionLanguageOptions } from './hook/useTranscriptionLanguageOptions'
+export { useSettingsDialog } from './hook/useSettingsDialog'
+
+export { SettingsDialogExtendedKey } from './type.ts'
diff --git a/src/frontend/src/features/settings/type.ts b/src/frontend/src/features/settings/type.ts
index e0a39b6d..0a1af14f 100644
--- a/src/frontend/src/features/settings/type.ts
+++ b/src/frontend/src/features/settings/type.ts
@@ -4,4 +4,5 @@ export enum SettingsDialogExtendedKey {
VIDEO = 'video',
GENERAL = 'general',
NOTIFICATIONS = 'notifications',
+ TRANSCRIPTION = 'transcription',
}
diff --git a/src/frontend/src/locales/de/rooms.json b/src/frontend/src/locales/de/rooms.json
index f93458ae..c72c1fba 100644
--- a/src/frontend/src/locales/de/rooms.json
+++ b/src/frontend/src/locales/de/rooms.json
@@ -317,7 +317,7 @@
"receiver": "Das Transkript wird an den Organisator und die Mitorganisatoren gesendet.",
"destination": "Ein neues Dokument wird erstellt auf",
"destinationUnknown": "Ein neues Dokument wird erstellt",
- "language": "Meeting-Sprachen: Französisch (fr)",
+ "language": "Meeting-Sprache:",
"recording": "Auch eine Aufzeichnung starten"
},
"button": {
diff --git a/src/frontend/src/locales/de/settings.json b/src/frontend/src/locales/de/settings.json
index 873b9994..c8a91204 100644
--- a/src/frontend/src/locales/de/settings.json
+++ b/src/frontend/src/locales/de/settings.json
@@ -68,6 +68,17 @@
},
"permissionsRequired": "Berechtigungen erforderlich"
},
+ "transcription": {
+ "heading": "Transkription",
+ "language": {
+ "label": "Besprechungssprache",
+ "options": {
+ "french": "Französisch (fr)",
+ "english": "Englisch (en)",
+ "auto": "Automatisch"
+ }
+ }
+ },
"notifications": {
"heading": "Tonbenachrichtigungen",
"label": "Tonbenachrichtigungen für",
@@ -100,6 +111,7 @@
"audio": "Audio",
"video": "Video",
"general": "Allgemein",
- "notifications": "Benachrichtigungen"
+ "notifications": "Benachrichtigungen",
+ "transcription": "Transkription"
}
}
diff --git a/src/frontend/src/locales/en/rooms.json b/src/frontend/src/locales/en/rooms.json
index 5eae0399..a58b7154 100644
--- a/src/frontend/src/locales/en/rooms.json
+++ b/src/frontend/src/locales/en/rooms.json
@@ -317,7 +317,7 @@
"receiver": "The transcript will be sent to the host and co-hosts.",
"destination": "A new document will be created on",
"destinationUnknown": "A new document will be created",
- "language": "Meeting language: French (fr)",
+ "language": "Meeting language:",
"recording": "Also start a recording"
},
"button": {
diff --git a/src/frontend/src/locales/en/settings.json b/src/frontend/src/locales/en/settings.json
index eb7bb294..3deecec1 100644
--- a/src/frontend/src/locales/en/settings.json
+++ b/src/frontend/src/locales/en/settings.json
@@ -68,6 +68,17 @@
},
"permissionsRequired": "Permissions required"
},
+ "transcription": {
+ "heading": "Transcription",
+ "language": {
+ "label": "Meeting language",
+ "options": {
+ "french": "French (fr)",
+ "english": "English (en)",
+ "auto": "Automatic"
+ }
+ }
+ },
"notifications": {
"heading": "Sound notifications",
"label": "sound notifications for",
@@ -100,6 +111,7 @@
"audio": "Audio",
"video": "Video",
"general": "General",
- "notifications": "Notifications"
+ "notifications": "Notifications",
+ "transcription": "Transcription"
}
}
diff --git a/src/frontend/src/locales/fr/rooms.json b/src/frontend/src/locales/fr/rooms.json
index 56e87e34..c9066505 100644
--- a/src/frontend/src/locales/fr/rooms.json
+++ b/src/frontend/src/locales/fr/rooms.json
@@ -317,7 +317,7 @@
"receiver": "La transcription sera envoyée à l'organisateur et aux coorganisateurs.",
"destination": "Un nouveau document sera créé sur",
"destinationUnknown": "Un nouveau document sera créé",
- "language": "Langues de la réunion : Français (fr)",
+ "language": "Langue de la réunion :",
"recording": "Démarrer aussi un enregistrement"
},
"button": {
diff --git a/src/frontend/src/locales/fr/settings.json b/src/frontend/src/locales/fr/settings.json
index bc1704e3..53df0074 100644
--- a/src/frontend/src/locales/fr/settings.json
+++ b/src/frontend/src/locales/fr/settings.json
@@ -68,6 +68,17 @@
},
"permissionsRequired": "Autorisations nécessaires"
},
+ "transcription": {
+ "heading": "Transcription",
+ "language": {
+ "label": "Langue de la réunion",
+ "options": {
+ "french": "Français (fr)",
+ "english": "Anglais (en)",
+ "auto": "Automatique"
+ }
+ }
+ },
"notifications": {
"heading": "Notifications sonores",
"label": "la notification sonore pour",
@@ -100,6 +111,7 @@
"audio": "Audio",
"video": "Vidéo",
"general": "Général",
- "notifications": "Notifications"
+ "notifications": "Notifications",
+ "transcription": "Transcription"
}
}
diff --git a/src/frontend/src/locales/nl/rooms.json b/src/frontend/src/locales/nl/rooms.json
index 99bbaaca..dadc34bb 100644
--- a/src/frontend/src/locales/nl/rooms.json
+++ b/src/frontend/src/locales/nl/rooms.json
@@ -317,7 +317,7 @@
"receiver": "Het transcript wordt verzonden naar de organisator en medeorganisatoren.",
"destination": "Er wordt een nieuw document aangemaakt op",
"destinationUnknown": "Een nieuw document wordt aangemaakt",
- "language": "Vergadertalen: Frans (fr)",
+ "language": "Vergadertalen:",
"recording": "Start ook een opname"
},
"button": {
diff --git a/src/frontend/src/locales/nl/settings.json b/src/frontend/src/locales/nl/settings.json
index 50c34dc7..340560c1 100644
--- a/src/frontend/src/locales/nl/settings.json
+++ b/src/frontend/src/locales/nl/settings.json
@@ -68,6 +68,17 @@
},
"permissionsRequired": "Machtigingen vereist"
},
+ "transcription": {
+ "heading": "Transcriptie",
+ "language": {
+ "label": "Vergadertaal",
+ "options": {
+ "french": "Frans (fr)",
+ "english": "Engels (en)",
+ "auto": "Automatisch"
+ }
+ }
+ },
"notifications": {
"heading": "Geluidsmeldingen",
"label": "Geluidsmeldingen voor",
@@ -100,6 +111,7 @@
"audio": "Audio",
"video": "Video",
"general": "Algemeen",
- "notifications": "Meldingen"
+ "notifications": "Meldingen",
+ "transcription": "Transcriptie"
}
}
diff --git a/src/frontend/src/stores/recording.ts b/src/frontend/src/stores/recording.ts
index 8ce95600..661dbe66 100644
--- a/src/frontend/src/stores/recording.ts
+++ b/src/frontend/src/stores/recording.ts
@@ -1,5 +1,11 @@
import { proxy } from 'valtio'
+export enum RecordingLanguage {
+ ENGLISH = 'en',
+ FRENCH = 'fr',
+ AUTOMATIC = 'auto',
+}
+
export enum RecordingStatus {
TRANSCRIPT_STARTING,
TRANSCRIPT_STARTED,
@@ -13,8 +19,10 @@ export enum RecordingStatus {
type State = {
status: RecordingStatus
+ language: RecordingLanguage
}
export const recordingStore = proxy({
status: RecordingStatus.STOPPED,
+ language: RecordingLanguage.FRENCH,
})