PluginProbe
AI Builder – Generate pages, blocks, images & translate with AI / 2.2.3
AI Builder – Generate pages, blocks, images & translate with AI v2.2.3
2.8.0 2.7.10 2.7.9 2.7.8 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 All 123 releases
ai-builder / assets / js / translation.js

translation.js in AI Builder – Generate pages, blocks, images & translate with AI 2.2.3, at assets/js/translation.js

192 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Translation with AI - JavaScript Handler
3 */
4
5 (function ($) {
6 'use strict';
7
8 let translationModal = null;
9
10 /**
11 * Create and show translation modal
12 */
13 function showTranslationModal(postId, nonce) {
14 // Remove existing modal if any
15 if (translationModal) {
16 translationModal.remove();
17 }
18
19 // Create modal HTML
20 const modalHTML = `
21 <div id="aibui-translation-modal" class="aibui-modal-overlay">
22 <div class="aibui-modal-content">
23 <div class="aibui-modal-header">
24 <h2>✨ Translate with AI</h2>
25 <button class="aibui-modal-close" aria-label="Close">&times;</button>
26 </div>
27 <div class="aibui-modal-body">
28 <p>Select the target language for translation:</p>
29 <div class="aibui-form-group">
30 <label for="aibui-target-lang">Target Language:</label>
31 <select id="aibui-target-lang" class="aibui-select">
32 <option value="">-- Select Language --</option>
33 ${Object.entries(aibuiTranslation.languages).map(([code, name]) =>
34 `<option value="${code}">${name}</option>`
35 ).join('')}
36 </select>
37 </div>
38 <div class="aibui-modal-message" id="aibui-modal-message" style="display: none;"></div>
39 </div>
40 <div class="aibui-modal-footer">
41 <button type="button" class="button button-secondary aibui-modal-cancel">Cancel</button>
42 <button type="button" class="button button-primary aibui-modal-translate" data-post-id="${postId}" data-nonce="${nonce}">
43 <span class="aibui-translate-text">Translate</span>
44 <span class="aibui-loading-spinner" style="display: none;">
45 <span class="spinner is-active" style="float: none; margin: 0;"></span>
46 </span>
47 </button>
48 </div>
49 </div>
50 </div>
51 `;
52
53 // Append to body
54 $('body').append(modalHTML);
55 translationModal = $('#aibui-translation-modal');
56
57 // Show modal with fade-in
58 setTimeout(() => {
59 translationModal.addClass('aibui-modal-visible');
60 }, 10);
61
62 // Close handlers
63 translationModal.find('.aibui-modal-close, .aibui-modal-cancel').on('click', closeModal);
64 translationModal.on('click', function (e) {
65 if ($(e.target).hasClass('aibui-modal-overlay')) {
66 closeModal();
67 }
68 });
69
70 // Escape key handler
71 $(document).on('keydown.aibuiTranslation', function (e) {
72 if (e.key === 'Escape' && translationModal && translationModal.hasClass('aibui-modal-visible')) {
73 closeModal();
74 }
75 });
76
77 // Translate button handler
78 translationModal.find('.aibui-modal-translate').on('click', function () {
79 const $button = $(this);
80 const targetLang = $('#aibui-target-lang').val();
81
82 if (!targetLang) {
83 showMessage('Please select a target language.', 'error');
84 return;
85 }
86
87 handleTranslation($button, postId, targetLang, nonce);
88 });
89 }
90
91 /**
92 * Close modal
93 */
94 function closeModal() {
95 if (translationModal) {
96 translationModal.removeClass('aibui-modal-visible');
97 setTimeout(() => {
98 translationModal.remove();
99 translationModal = null;
100 $(document).off('keydown.aibuiTranslation');
101 }, 300);
102 }
103 }
104
105 /**
106 * Show message in modal
107 */
108 function showMessage(message, type) {
109 const $messageEl = $('#aibui-modal-message');
110 $messageEl
111 .removeClass('aibui-message-error aibui-message-success')
112 .addClass('aibui-message-' + type)
113 .text(message)
114 .fadeIn();
115
116 if (type === 'success') {
117 setTimeout(() => {
118 $messageEl.fadeOut();
119 }, 3000);
120 }
121 }
122
123 /**
124 * Handle translation AJAX request
125 */
126 function handleTranslation($button, postId, targetLang, nonce) {
127 const $translateText = $button.find('.aibui-translate-text');
128 const $spinner = $button.find('.aibui-loading-spinner');
129
130 // Disable button and show loading
131 $button.prop('disabled', true);
132 $translateText.hide();
133 $spinner.show();
134
135 // Clear previous messages
136 $('#aibui-modal-message').hide();
137
138 // Make AJAX request
139 $.ajax({
140 url: aibuiTranslation.ajaxurl,
141 type: 'POST',
142 timeout: 180000, // 5 minutes - AI translation can take longer for large pages
143 data: {
144 action: 'aibui_translate_post',
145 nonce: aibuiTranslation.nonce,
146 post_id: postId,
147 target_lang: targetLang,
148 },
149 success: function (response) {
150 if (response.success) {
151 showMessage('Translation created successfully! Redirecting...', 'success');
152
153 // Redirect to edit page after short delay
154 setTimeout(() => {
155 if (response.data && response.data.edit_url) {
156 window.location.href = response.data.edit_url;
157 } else {
158 window.location.reload();
159 }
160 }, 1500);
161 } else {
162 showMessage(response.data?.message || 'Translation failed. Please try again.', 'error');
163 $button.prop('disabled', false);
164 $translateText.show();
165 $spinner.hide();
166 }
167 },
168 error: function (xhr, status, error) {
169 showMessage('Network error. Please try again.', 'error');
170 $button.prop('disabled', false);
171 $translateText.show();
172 $spinner.hide();
173 }
174 });
175 }
176
177 /**
178 * Initialize on document ready
179 */
180 $(document).ready(function () {
181 // Handle click on translate link
182 $(document).on('click', '.aibui-translate-link', function (e) {
183 e.preventDefault();
184 const postId = $(this).data('post-id');
185 const nonce = $(this).data('nonce');
186 showTranslationModal(postId, nonce);
187 });
188 });
189
190 })(jQuery);
191
192