| @@ -83,9 +83,9 @@ | ||
| 83 | 83 | alignItems: 'center', |
| 84 | 84 | justifyContent: 'space-between' |
| 85 | 85 | }); |
| 86 | 86 | $errorMessage.html( |
| 87 | - '<span>OpenAI API key is missing or invalid. Please configure your API key in AI Settings.</span>' + | |
| 87 | + '<span>' + ((window.KingAddonsAiImageField && KingAddonsAiImageField.missing_key_message) || 'The AI API key is missing or invalid. Please configure your API key in AI Settings.') + '</span>' + | |
| 88 | 88 | '<a href="' + settingsUrl + '" style="color:#0073aa;text-decoration:underline;white-space:nowrap;margin-left:10px;" target="_blank">Settings</a>' |
| 89 | 89 | ); |
| 90 | 90 | $wrapper.after($errorMessage).hide().fadeIn(200); |
| 91 | 91 | setTimeout(function() { $errorMessage.fadeOut(200, function() { $(this).remove(); }); }, 5000); |
| @@ -109,21 +109,27 @@ | ||
| 109 | 109 | ]; |
| 110 | 110 | resolutions.forEach(function(res) { |
| 111 | 111 | $resolution.append('<option value="' + res.value + '">' + res.label + '</option>'); |
| 112 | 112 | }); |
| 113 | - // Model selector reflecting saved default | |
| 113 | + // Model selector reflecting the configured provider and default | |
| 114 | 114 | var $modelSelect = $('<select class="kng-ai-image-model" style="margin-right:6px;"></select>'); |
| 115 | - var imageModels = [ | |
| 116 | - { value: 'dall-e-3', label: 'DALL·E 3' }, | |
| 117 | - { value: 'gpt-image-1', label: 'GPT Image 1' } | |
| 118 | - ]; | |
| 115 | + var imageModels = KingAddonsAiImageField.image_models; | |
| 116 | + if (!Array.isArray(imageModels) || !imageModels.length) { | |
| 117 | + imageModels = [ | |
| 118 | + { value: 'dall-e-3', label: 'DALL\u00b7E 3' }, | |
| 119 | + { value: 'gpt-image-1', label: 'GPT Image 1' } | |
| 120 | + ]; | |
| 121 | + } | |
| 119 | 122 | imageModels.forEach(function(m) { |
| 120 | - $modelSelect.append('<option value="' + m.value + '">' + m.label + '</option>'); | |
| 123 | + $modelSelect.append($('<option></option>').val(m.value).text(m.label)); | |
| 121 | 124 | }); |
| 122 | 125 | // Apply default from settings |
| 123 | 126 | if (KingAddonsAiImageField.image_model) { |
| 124 | 127 | $modelSelect.val(KingAddonsAiImageField.image_model); |
| 125 | 128 | } |
| 129 | + if (!$modelSelect.val() && imageModels.length) { | |
| 130 | + $modelSelect.val(imageModels[0].value); | |
| 131 | + } | |
| 126 | 132 | // Define controls per model |
| 127 | 133 | var modelControls = { |
| 128 | 134 | 'dall-e-3': { |
| 129 | 135 | qualities: [ |
| @@ -150,19 +156,33 @@ | ||
| 150 | 156 | { value: '1024x1536', label: '1024×1536 (portrait)' } |
| 151 | 157 | ] |
| 152 | 158 | } |
| 153 | 159 | }; |
| 154 | - // Function to update selects based on chosen model | |
| 160 | + // Function to update selects based on chosen model. Models that | |
| 161 | + // are not OpenAI's own (for example anything routed through | |
| 162 | + // OpenRouter) take no quality/size arguments, so those rows are | |
| 163 | + // hidden rather than sending options the provider will reject. | |
| 155 | 164 | function updateControlsByModel() { |
| 156 | 165 | var m = $modelSelect.val(); |
| 166 | + var controls = modelControls[m]; | |
| 167 | + | |
| 168 | + if (!controls) { | |
| 169 | + $quality.empty().closest('.kng-ai-image-field-row').hide(); | |
| 170 | + $resolution.empty().closest('.kng-ai-image-field-row').hide(); | |
| 171 | + return; | |
| 172 | + } | |
| 173 | + | |
| 174 | + $quality.closest('.kng-ai-image-field-row').show(); | |
| 175 | + $resolution.closest('.kng-ai-image-field-row').show(); | |
| 176 | + | |
| 157 | 177 | // update quality options |
| 158 | 178 | $quality.empty(); |
| 159 | - modelControls[m].qualities.forEach(function(opt) { | |
| 179 | + controls.qualities.forEach(function(opt) { | |
| 160 | 180 | $quality.append('<option value="'+opt.value+'">'+opt.label+'</option>'); |
| 161 | 181 | }); |
| 162 | 182 | // update size options |
| 163 | 183 | $resolution.empty(); |
| 164 | - modelControls[m].sizes.forEach(function(opt) { | |
| 184 | + controls.sizes.forEach(function(opt) { | |
| 165 | 185 | $resolution.append('<option value="'+opt.value+'">'+opt.label+'</option>'); |
| 166 | 186 | }); |
| 167 | 187 | } |
| 168 | 188 | // Bind change handler and initialize |
| @@ -205,8 +225,11 @@ | ||
| 205 | 225 | $cancel |
| 206 | 226 | ) |
| 207 | 227 | ); |
| 208 | 228 | $outer.append($promptContainer); |
| 229 | + // Re-run now that the rows exist, so a model without quality / | |
| 230 | + // size options can hide them. | |
| 231 | + updateControlsByModel(); | |
| 209 | 232 | // Add user note about processing time |
| 210 | 233 | $promptContainer.append($('<p class="kng-ai-image-prompt-note">Complex prompts may take up to 2 minutes to process.</p>')); |
| 211 | 234 | // Mark the Generate Image button as active (container open) |
| 212 | 235 | $btn.addClass('is-active'); |