@@ -77,12 +77,19 @@ import {
7777 getProviderStatusDescription ,
7878 getProviderStatusHeading ,
7979} from "../components/chat/providerStatusPresentation" ;
80+ import { APP_LOCALE_PREFERENCES } from "../i18n/types" ;
81+ import { useT } from "../i18n/useI18n" ;
8082
81- const TIMESTAMP_FORMAT_LABELS = {
82- locale : "System default" ,
83- "12-hour" : "12-hour" ,
84- "24-hour" : "24-hour" ,
85- } as const ;
83+ const TIMESTAMP_FORMAT_OPTIONS = [
84+ { value : "locale" , labelKey : "settings.general.timeFormat.option.locale" } ,
85+ { value : "12-hour" , labelKey : "settings.general.timeFormat.option.12Hour" } ,
86+ { value : "24-hour" , labelKey : "settings.general.timeFormat.option.24Hour" } ,
87+ ] as const ;
88+
89+ const LANGUAGE_OPTIONS = APP_LOCALE_PREFERENCES . map ( ( value ) => ( {
90+ value,
91+ labelKey : `settings.general.language.option.${ value } ` as const ,
92+ } ) ) ;
8693
8794const PR_REVIEW_REQUEST_CHANGES_TONE_OPTIONS : ReadonlyArray < {
8895 value : PrReviewRequestChangesTone ;
@@ -435,6 +442,7 @@ function BuildInfoBlock({ label, buildInfo }: { label: string; buildInfo: BuildM
435442}
436443
437444function SettingsRouteView ( ) {
445+ const { t } = useT ( ) ;
438446 const navigate = useNavigate ( ) ;
439447 const {
440448 settingsState : { settings, defaults, updateSettings } ,
@@ -709,6 +717,15 @@ function SettingsRouteView() {
709717 [ settings , updateSettings ] ,
710718 ) ;
711719
720+ const languageOptionLabel = ( value : ( typeof APP_LOCALE_PREFERENCES ) [ number ] ) =>
721+ t ( `settings.general.language.option.${ value } ` ) ;
722+
723+ const timestampFormatOptionLabel = ( value : ( typeof TIMESTAMP_FORMAT_OPTIONS ) [ number ] [ "value" ] ) =>
724+ t (
725+ TIMESTAMP_FORMAT_OPTIONS . find ( ( option ) => option . value === value ) ?. labelKey ??
726+ "settings.general.timeFormat.option.locale" ,
727+ ) ;
728+
712729 return (
713730 < SettingsShell
714731 activeItem = { activeSection }
@@ -736,6 +753,50 @@ function SettingsRouteView() {
736753 }
737754 />
738755
756+ < SettingsRow
757+ title = { t ( "settings.general.language.title" ) }
758+ description = { t ( "settings.general.language.description" ) }
759+ resetAction = {
760+ settings . locale !== defaults . locale ? (
761+ < SettingResetButton
762+ label = "language"
763+ onClick = { ( ) =>
764+ updateSettings ( {
765+ locale : defaults . locale ,
766+ } )
767+ }
768+ />
769+ ) : null
770+ }
771+ control = {
772+ < Select
773+ value = { settings . locale }
774+ onValueChange = { ( value ) => {
775+ if ( ! LANGUAGE_OPTIONS . some ( ( option ) => option . value === value ) ) {
776+ return ;
777+ }
778+ updateSettings ( {
779+ locale : value as ( typeof APP_LOCALE_PREFERENCES ) [ number ] ,
780+ } ) ;
781+ } }
782+ >
783+ < SelectTrigger
784+ className = "w-full sm:w-40"
785+ aria-label = { t ( "settings.general.language.aria" ) }
786+ >
787+ < SelectValue > { languageOptionLabel ( settings . locale ) } </ SelectValue >
788+ </ SelectTrigger >
789+ < SelectPopup align = "end" alignItemWithTrigger = { false } >
790+ { LANGUAGE_OPTIONS . map ( ( option ) => (
791+ < SelectItem hideIndicator key = { option . value } value = { option . value } >
792+ { languageOptionLabel ( option . value ) }
793+ </ SelectItem >
794+ ) ) }
795+ </ SelectPopup >
796+ </ Select >
797+ }
798+ />
799+
739800 < SettingsRow
740801 title = "PR request changes button"
741802 description = "Choose how prominent the Request changes action looks in pull request review."
@@ -800,27 +861,25 @@ function SettingsRouteView() {
800861 < Select
801862 value = { settings . timestampFormat }
802863 onValueChange = { ( value ) => {
803- if ( value !== "locale" && value !== "12-hour" && value !== "24-hour" ) {
864+ if ( ! TIMESTAMP_FORMAT_OPTIONS . some ( ( option ) => option . value === value ) ) {
804865 return ;
805866 }
806867 updateSettings ( {
807- timestampFormat : value ,
868+ timestampFormat : value as ( typeof TIMESTAMP_FORMAT_OPTIONS ) [ number ] [ "value" ] ,
808869 } ) ;
809870 } }
810871 >
811872 < SelectTrigger className = "w-full sm:w-40" aria-label = "Timestamp format" >
812- < SelectValue > { TIMESTAMP_FORMAT_LABELS [ settings . timestampFormat ] } </ SelectValue >
873+ < SelectValue >
874+ { timestampFormatOptionLabel ( settings . timestampFormat ) }
875+ </ SelectValue >
813876 </ SelectTrigger >
814877 < SelectPopup align = "end" alignItemWithTrigger = { false } >
815- < SelectItem hideIndicator value = "locale" >
816- { TIMESTAMP_FORMAT_LABELS . locale }
817- </ SelectItem >
818- < SelectItem hideIndicator value = "12-hour" >
819- { TIMESTAMP_FORMAT_LABELS [ "12-hour" ] }
820- </ SelectItem >
821- < SelectItem hideIndicator value = "24-hour" >
822- { TIMESTAMP_FORMAT_LABELS [ "24-hour" ] }
823- </ SelectItem >
878+ { TIMESTAMP_FORMAT_OPTIONS . map ( ( option ) => (
879+ < SelectItem hideIndicator key = { option . value } value = { option . value } >
880+ { timestampFormatOptionLabel ( option . value ) }
881+ </ SelectItem >
882+ ) ) }
824883 </ SelectPopup >
825884 </ Select >
826885 }
0 commit comments