@@ -369,10 +369,124 @@ function optionsGetModelConfig(model: string): ModelConfig | undefined {
369369 return models [ model ] ;
370370}
371371
372+ // Populate AI Model dropdown dynamically
373+ function populateModelDropdown ( ) {
374+ console . log ( 'populateModelDropdown called' ) ;
375+ const selectedModelSelect = document . getElementById (
376+ 'selectedModel'
377+ ) as HTMLSelectElement ;
378+ console . log ( 'selectedModelSelect element:' , selectedModelSelect ) ;
379+ console . log (
380+ 'selectedModelSelect options:' ,
381+ selectedModelSelect ? selectedModelSelect . options : 'No element found'
382+ ) ;
383+ console . log (
384+ 'selectedModelSelect children:' ,
385+ selectedModelSelect ? selectedModelSelect . children : 'No element found'
386+ ) ;
387+ console . log (
388+ 'selectedModelSelect innerHTML:' ,
389+ selectedModelSelect ? selectedModelSelect . innerHTML : 'No element found'
390+ ) ;
391+ if ( ! selectedModelSelect ) {
392+ console . log ( 'selectedModelSelect not found' ) ;
393+ return ;
394+ }
395+
396+ // Clear existing options
397+ selectedModelSelect . innerHTML = '' ;
398+ console . log ( 'Cleared existing options' ) ;
399+
400+ // Define model groups with their configurations
401+ const modelGroups = [
402+ {
403+ labelKey : 'freeModels' ,
404+ models : [
405+ { value : 'chrome-builtin' , i18nKey : 'chromeAiFree' } ,
406+ { value : 'gemini-2.0-flash-exp' , i18nKey : 'gemini20FlashExp' } ,
407+ ] ,
408+ } ,
409+ {
410+ labelKey : 'openaiModels' ,
411+ models : [
412+ { value : 'gpt-3.5-turbo' , i18nKey : 'gpt35Turbo' } ,
413+ { value : 'gpt-4' , i18nKey : 'gpt4' } ,
414+ { value : 'gpt-4-turbo' , i18nKey : 'gpt4Turbo' } ,
415+ { value : 'gpt-4o' , i18nKey : 'gpt4o' } ,
416+ { value : 'gpt-5' , i18nKey : 'gpt5' } ,
417+ { value : 'gpt-5-mini' , i18nKey : 'gpt5Mini' } ,
418+ { value : 'gpt-5-nano' , i18nKey : 'gpt5Nano' } ,
419+ ] ,
420+ } ,
421+ {
422+ labelKey : 'googleGeminiModels' ,
423+ models : [
424+ { value : 'gemini-2.5-pro' , i18nKey : 'gemini25Pro' } ,
425+ { value : 'gemini-2.5-flash' , i18nKey : 'gemini25Flash' } ,
426+ ] ,
427+ } ,
428+ {
429+ labelKey : 'anthropicClaudeModels' ,
430+ models : [
431+ { value : 'claude-3-haiku' , i18nKey : 'claude3Haiku' } ,
432+ { value : 'claude-3-sonnet' , i18nKey : 'claude3Sonnet' } ,
433+ { value : 'claude-3-opus' , i18nKey : 'claude3Opus' } ,
434+ { value : 'claude-3.5-sonnet' , i18nKey : 'claude35Sonnet' } ,
435+ { value : 'claude-4.5-sonnet' , i18nKey : 'claudeSonnet45' } ,
436+ { value : 'claude-4.5-haiku' , i18nKey : 'claudeHaiku45' } ,
437+ ] ,
438+ } ,
439+ ] ;
440+
441+ console . log ( 'modelGroups defined:' , modelGroups ) ;
442+
443+ // Create optgroups and options
444+ modelGroups . forEach ( ( group , groupIndex ) => {
445+ console . log ( `Processing group ${ groupIndex } :` , group ) ;
446+ const optgroup = document . createElement ( 'optgroup' ) ;
447+ optgroup . setAttribute ( 'data-i18n' , group . labelKey ) ;
448+ optgroup . label = group . labelKey ; // Fallback label
449+ console . log ( `Created optgroup with label: ${ group . labelKey } ` ) ;
450+
451+ group . models . forEach ( ( model , modelIndex ) => {
452+ console . log (
453+ `Processing model ${ modelIndex } in group ${ groupIndex } :` ,
454+ model
455+ ) ;
456+ const option = document . createElement ( 'option' ) ;
457+ option . value = model . value ;
458+ option . setAttribute ( 'data-i18n' , model . i18nKey ) ;
459+ option . textContent = model . i18nKey ; // Fallback text
460+ console . log (
461+ `Created option with value: ${ model . value } , text: ${ model . i18nKey } `
462+ ) ;
463+ optgroup . appendChild ( option ) ;
464+ } ) ;
465+
466+ console . log (
467+ `Appending optgroup to select, optgroup children count: ${ optgroup . children . length } `
468+ ) ;
469+ selectedModelSelect . appendChild ( optgroup ) ;
470+ } ) ;
471+
472+ console . log (
473+ 'Final selectedModelSelect children count:' ,
474+ selectedModelSelect . children . length
475+ ) ;
476+ console . log (
477+ 'Final selectedModelSelect innerHTML:' ,
478+ selectedModelSelect . innerHTML
479+ ) ;
480+ }
481+
372482// Initialize i18n inside DOMContentLoaded to ensure DOM elements exist
373483document . addEventListener ( 'DOMContentLoaded' , async function ( ) {
374484 // Initialize i18n after DOM is ready
375485 await initializeI18n ( ) ;
486+ // Populate model dropdown after i18n is ready
487+ populateModelDropdown ( ) ;
488+ // Update UI language to translate dynamically added elements
489+ updateUILanguage ( ) ;
376490 // Theme toggle functionality
377491 const themeToggle = document . getElementById (
378492 'themeToggle'
@@ -444,6 +558,8 @@ document.addEventListener('DOMContentLoaded', async function () {
444558 const selectedLanguage = languageSelect . value ;
445559 await setUserLanguage ( selectedLanguage ) ;
446560 updateUILanguage ( document , selectedLanguage ) ;
561+ // Repopulate model dropdown with new language translations
562+ populateModelDropdown ( ) ;
447563 } ) ;
448564 const temperatureInput = document . getElementById (
449565 'temperature'
@@ -896,74 +1012,6 @@ document.addEventListener('DOMContentLoaded', async function () {
8961012 refreshMetricsButton . addEventListener ( 'click' , loadMetrics ) ;
8971013
8981014 // Load and display history
899- // Populate AI Model dropdown dynamically
900- function populateModelDropdown ( ) {
901- const selectedModelSelect = document . getElementById (
902- 'selectedModel'
903- ) as HTMLSelectElement ;
904- if ( ! selectedModelSelect ) return ;
905-
906- // Clear existing options
907- selectedModelSelect . innerHTML = '' ;
908-
909- // Define model groups with their configurations
910- const modelGroups = [
911- {
912- labelKey : 'freeModels' ,
913- models : [
914- { value : 'chrome-builtin' , i18nKey : 'chromeAiFree' } ,
915- { value : 'gemini-2.0-flash-exp' , i18nKey : 'gemini20FlashExp' } ,
916- ] ,
917- } ,
918- {
919- labelKey : 'openaiModels' ,
920- models : [
921- { value : 'gpt-3.5-turbo' , i18nKey : 'gpt35Turbo' } ,
922- { value : 'gpt-4' , i18nKey : 'gpt4' } ,
923- { value : 'gpt-4-turbo' , i18nKey : 'gpt4Turbo' } ,
924- { value : 'gpt-4o' , i18nKey : 'gpt4o' } ,
925- { value : 'gpt-5' , i18nKey : 'gpt5' } ,
926- { value : 'gpt-5-mini' , i18nKey : 'gpt5Mini' } ,
927- { value : 'gpt-5-nano' , i18nKey : 'gpt5Nano' } ,
928- ] ,
929- } ,
930- {
931- labelKey : 'googleGeminiModels' ,
932- models : [
933- { value : 'gemini-2.5-pro' , i18nKey : 'gemini25Pro' } ,
934- { value : 'gemini-2.5-flash' , i18nKey : 'gemini25Flash' } ,
935- ] ,
936- } ,
937- {
938- labelKey : 'anthropicClaudeModels' ,
939- models : [
940- { value : 'claude-3-haiku' , i18nKey : 'claude3Haiku' } ,
941- { value : 'claude-3-sonnet' , i18nKey : 'claude3Sonnet' } ,
942- { value : 'claude-3-opus' , i18nKey : 'claude3Opus' } ,
943- { value : 'claude-3.5-sonnet' , i18nKey : 'claude35Sonnet' } ,
944- { value : 'claude-4.5-sonnet' , i18nKey : 'claudeSonnet45' } ,
945- { value : 'claude-4.5-haiku' , i18nKey : 'claudeHaiku45' } ,
946- ] ,
947- } ,
948- ] ;
949-
950- // Create optgroups and options
951- modelGroups . forEach ( ( group ) => {
952- const optgroup = document . createElement ( 'optgroup' ) ;
953- optgroup . setAttribute ( 'data-i18n' , group . labelKey ) ;
954- optgroup . label = group . labelKey ; // Fallback label
955-
956- group . models . forEach ( ( model ) => {
957- const option = document . createElement ( 'option' ) ;
958- option . value = model . value ;
959- option . setAttribute ( 'data-i18n' , model . i18nKey ) ;
960- option . textContent = model . i18nKey ; // Fallback text
961- optgroup . appendChild ( option ) ;
962- } ) ;
963-
964- selectedModelSelect . appendChild ( optgroup ) ;
965- } ) ;
966- }
9671015 function loadHistory ( ) {
9681016 chrome . storage . local . get ( 'summaryHistory' , ( result ) => {
9691017 displayHistory ( result . summaryHistory || [ ] ) ;
0 commit comments