1(function($){ 2 // Definir o objeto YouTubeAnalyzerManager se não existir 3 if (typeof YouTubeAnalyzerManager === 'undefined') { 4 window.YouTubeAnalyzerManager = { 5 apiKeys: { 6 get: function() { 7 return $.ajax({ 8 url: youtube_analyzer_data.rest_url + 'api-keys', 9 method: 'GET', 10 beforeSend: function(xhr) { 11 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 12 } 13 }); 14 }, 15 save: function(keys) { 16 return $.ajax({ 17 url: youtube_analyzer_data.rest_url + 'api-keys', 18 method: 'POST', 19 contentType: 'application/json', 20 data: JSON.stringify(keys), 21 beforeSend: function(xhr) { 22 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 23 } 24 }); 25 } 26 }, 27 nichos: { 28 get: function() { 29 return $.ajax({ 30 url: youtube_analyzer_data.rest_url + 'nichos', 31 method: 'GET', 32 beforeSend: function(xhr) { 33 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 34 } 35 }); 36 }, 37 save: function(nichosData) { 38 return $.ajax({ 39 url: youtube_analyzer_data.rest_url + 'nichos', 40 method: 'POST', 41 contentType: 'application/json', 42 data: JSON.stringify(nichosData), 43 beforeSend: function(xhr) { 44 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 45 } 46 }); 47 }, 48 getUserNichos: function(userId) { 49 return $.ajax({ 50 url: youtube_analyzer_data.rest_url + 'nichos/user/' + userId, 51 method: 'GET', 52 beforeSend: function(xhr) { 53 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 54 } 55 }); 56 } 57 }, 58 // ADICIONAR O OBJETO SAVEDTEMS QUE ESTAVA FALTANDO 59 savedItems: { 60 // VÃdeos salvos 61 getVideos: function() { 62 return $.ajax({ 63 url: youtube_analyzer_data.rest_url + 'saved-items/videos', 64 method: 'GET', 65 beforeSend: function(xhr) { 66 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 67 } 68 }); 69 }, 70 saveVideos: function(videos) { 71 return $.ajax({ 72 url: youtube_analyzer_data.rest_url + 'saved-items/videos', 73 method: 'POST', 74 contentType: 'application/json', 75 data: JSON.stringify(videos), 76 beforeSend: function(xhr) { 77 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 78 } 79 }); 80 }, 81 // Canais salvos 82 getChannels: function() { 83 return $.ajax({ 84 url: youtube_analyzer_data.rest_url + 'saved-items/channels', 85 method: 'GET', 86 beforeSend: function(xhr) { 87 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 88 } 89 }); 90 }, 91 saveChannels: function(channels) { 92 return $.ajax({ 93 url: youtube_analyzer_data.rest_url + 'saved-items/channels', 94 method: 'POST', 95 contentType: 'application/json', 96 data: JSON.stringify(channels), 97 beforeSend: function(xhr) { 98 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 99 } 100 }); 101 }, 102 // Playlists salvas 103 getPlaylists: function() { 104 return $.ajax({ 105 url: youtube_analyzer_data.rest_url + 'saved-items/playlists', 106 method: 'GET', 107 beforeSend: function(xhr) { 108 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 109 } 110 }); 111 }, 112 savePlaylists: function(playlists) { 113 return $.ajax({ 114 url: youtube_analyzer_data.rest_url + 'saved-items/playlists', 115 method: 'POST', 116 contentType: 'application/json', 117 data: JSON.stringify(playlists), 118 beforeSend: function(xhr) { 119 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 120 } 121 }); 122 } 123 }, 124 users: { 125 getList: function() { 126 return $.ajax({ 127 url: youtube_analyzer_data.rest_url + 'users', 128 method: 'GET', 129 beforeSend: function(xhr) { 130 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 131 } 132 }); 133 } 134 } 135 }; 136 } 137 138 $(document).ready(function(){ 139 // Dispara evento para sobrescrita das funções de armazenamento 140 document.dispatchEvent(new Event('youtube_analyzer_manager_ready')); 141 }); 142 143 document.addEventListener('youtube_analyzer_manager_ready', function() { 144 console.log('YouTube Analyzer Manager pronto, substituindo funções de armazenamento...'); 145 146 // --- Gerenciamento de API Keys via WordPress --- 147 window.loadApiKeysFromWordPress = function() { 148 console.log('Carregando chaves API do WordPress...'); 149 $.ajax({ 150 url: youtube_analyzer_data.rest_url + 'api-keys', 151 method: 'GET', 152 beforeSend: function(xhr) { 153 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 154 } 155 }).done(function(data) { 156 window.youtubeApiKeys = data || []; 157 if (typeof updateApiKeyUI === 'function') { 158 updateApiKeyUI(); 159 } 160 console.log(window.youtubeApiKeys.length + ' chaves API carregadas com sucesso'); 161 }).fail(function(err) { 162 console.error('Erro ao carregar chaves API:', err); 163 // Fallback para localStorage 164 const localKey = localStorage.getItem('youtubeApiKey'); 165 const localKeys = localStorage.getItem('youtubeApiKeys'); 166 167 if (localKeys && localKeys !== 'null') { 168 try { 169 window.youtubeApiKeys = JSON.parse(localKeys); 170 } catch (e) { 171 if (localKey && localKey !== 'null') { 172 window.youtubeApiKeys = [localKey]; 173 } else { 174 window.youtubeApiKeys = []; 175 } 176 } 177 } else if (localKey && localKey !== 'null') { 178 window.youtubeApiKeys = [localKey]; 179 } else { 180 window.youtubeApiKeys = []; 181 } 182 183 if (typeof updateApiKeyUI === 'function') { 184 updateApiKeyUI(); 185 } 186 }); 187 }; 188 189 window.saveApiKeysToWordPress = function(callback) { 190 console.log('ð¾ === SALVANDO NO WORDPRESS ==='); 191 console.log('ð Total a salvar:', window.youtubeApiKeys.length); 192 console.log('ð Chaves:', window.youtubeApiKeys.map((k, i) => `${i+1}: ${k.substring(0, 10)}...`)); 193 194 $.ajax({ 195 url: youtube_analyzer_data.rest_url + 'api-keys', 196 method: 'POST', 197 contentType: 'application/json', 198 data: JSON.stringify(window.youtubeApiKeys), 199 beforeSend: function(xhr) { 200 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 201 } 202 }).done(function(response) { 203 console.log('â Resposta:', response); 204 console.log('ð Total após salvar:', window.youtubeApiKeys.length); 205 206 localStorage.removeItem('youtubeApiKey'); 207 localStorage.removeItem('youtubeApiKeys'); 208 209 if (callback) callback(true); 210 }).fail(function(err) { 211 console.error('â Erro:', err); 212 if (callback) callback(false); 213 }); 214}; 215 216 // --- Gerenciamento de Nichos via WordPress ---
217 window.loadNichosFromWordPress = function() { 218 console.log('Carregando nichos do WordPress...'); 219 $.ajax({ 220 url: youtube_analyzer_data.rest_url + 'nichos', 221 method: 'GET', 222 beforeSend: function(xhr) { 223 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 224 } 225 }).done(function(data) { 226 if (typeof renderNichos === 'function') { 227 renderNichos(data || []); 228 } 229 console.log((data||[]).length + ' nichos carregados com sucesso'); 230 }).fail(function(err) { 231 console.error('Erro ao carregar nichos:', err); 232 // Fallback para localStorage 233 try { 234 const localNichos = JSON.parse(localStorage.getItem('userNichos') || '[]'); 235 if (typeof renderNichos === 'function') { 236 renderNichos(localNichos); 237 } 238 } catch (e) { 239 console.error('Erro no fallback localStorage:', e); 240 if (typeof renderNichos === 'function') { 241 renderNichos([]); 242 } 243 } 244 }); 245 }; 246 247 window.saveNichosToWordPress = function(nichosData, callback) { 248 console.log('Salvando nichos no WordPress...'); 249 $.ajax({ 250 url: youtube_analyzer_data.rest_url + 'nichos', 251 method: 'POST', 252 contentType: 'application/json', 253 data: JSON.stringify(nichosData), 254 beforeSend: function(xhr) { 255 xhr.setRequestHeader('X-WP-Nonce', youtube_analyzer_data.nonce); 256 } 257 }).done(function(response) { 258 console.log('Nichos salvos com sucesso'); 259 // Remover do localStorage após salvamento no WordPress 260 localStorage.removeItem('userNichos'); 261 if (callback) callback(true); 262 }).fail(function(err) { 263 console.error('Erro ao salvar nichos:', err); 264 // Fallback: salvar no localStorage 265 localStorage.setItem('userNichos', JSON.stringify(nichosData)); 266 if (callback) callback(false); 267 }); 268 }; 269 270 // --- Gerenciamento de Itens Salvos via WordPress --- 271 window.loadSavedItemsFromWordPress = function(type) { 272 return new Promise((resolve, reject) => { 273 let ajaxCall; 274 275 switch(type) { 276 case 'videos': 277 ajaxCall = YouTubeAnalyzerManager.savedItems.getVideos(); 278 break; 279 case 'channels': 280 ajaxCall = YouTubeAnalyzerManager.savedItems.getChannels(); 281 break; 282 case 'playlists': 283 ajaxCall = YouTubeAnalyzerManager.savedItems.getPlaylists(); 284 break; 285 default: 286 reject(new Error('Tipo inválido: ' + type)); 287 return; 288 } 289 290 ajaxCall.done(function(data) { 291 console.log(`${type} carregados do WordPress:`, data); 292 resolve(data || []); 293 }).fail(function(err) { 294 console.error(`Erro ao carregar ${type}:`, err); 295 // Fallback para localStorage 296 const localStorageKey = `saved${type.charAt(0).toUpperCase() + type.slice(1, -1)}s`; 297 try { 298 const localData = JSON.parse(localStorage.getItem(localStorageKey) || '[]'); 299 console.log(`Fallback: carregando ${type} do localStorage:`, localData); 300 resolve(localData); 301 } catch (e) { 302 console.error(`Erro no fallback localStorage para ${type}:`, e); 303 resolve([]); 304 } 305 }); 306 }); 307 }; 308 309 window.saveSavedItemsToWordPress = function(type, items, c
309allback) { 310 console.log(`Salvando ${type} no WordPress:`, items); 311 312 let ajaxCall; 313 314 switch(type) { 315 case 'videos': 316 ajaxCall = YouTubeAnalyzerManager.savedItems.saveVideos(items); 317 break; 318 case 'channels': 319 ajaxCall = YouTubeAnalyzerManager.savedItems.saveChannels(items); 320 break; 321 case 'playlists': 322 ajaxCall = YouTubeAnalyzerManager.savedItems.savePlaylists(items); 323 break; 324 default: 325 console.error('Tipo inválido:', type); 326 if (callback) callback(false); 327 return; 328 } 329 330 ajaxCall.done(function(response) { 331 console.log(`${type} salvos com sucesso no WordPress`); 332 // Remover do localStorage após salvamento no WordPress 333 const localStorageKey = `saved${type.charAt(0).toUpperCase() + type.slice(1, -1)}s`; 334 localStorage.removeItem(localStorageKey); 335 if (callback) callback(true); 336 }).fail(function(err) { 337 console.error(`Erro ao salvar ${type}:`, err); 338 // Fallback: salvar no localStorage 339 const localStorageKey = `saved${type.charAt(0).toUpperCase() + type.slice(1, -1)}s`; 340 localStorage.setItem(localStorageKey, JSON.stringify(items)); 341 if (callback) callback(false); 342 }); 343 }; 344 345 // Função segura para remover elementos 346 window.safeRemoveElement = function(element) { 347 if (element && element.parentNode) { 348 element.parentNode.removeChild(element); 349 return true; 350 } 351 return false; 352 }; 353 354 // Função para mostrar notificações com remoção segura 355 window.showNotification = function(message, isError = false) { 356 // Remover notificações existentes com segurança 357 const existingNotifications = document.querySelectorAll('.notification'); 358 existingNotifications.forEach(notification => { 359 safeRemoveElement(notification); 360 }); 361 362 // Criar nova notificação 363 const notification = document.createElement('div'); 364 notification.className = 'notification' + (isError ? ' error' : ''); 365 notification.textContent = message; 366 document.body.appendChild(notification); 367 368 // Mostrar com animação e configurar timer para remover 369 setTimeout(() => { 370 notification.classList.add('show'); 371 }, 10); 372 373 setTimeout(() => { 374 notification.classList.remove('show'); 375 setTimeout(() => { 376 // Verificar se o elemento ainda existe antes de tentar remover 377 safeRemoveElement(notification); 378 }, 300); 379 }, 3000); 380 }; 381 382 console.log('Funções de armazenamento substituÃdas com sucesso!'); 383 }); 384 385})(jQuery); 386 387// Definir getCurrentApiKey e switchToNextApiKey globalmente 388window.getCurrentApiKey = function() { 389 console.log('getCurrentApiKey() chamada'); 390 391 // Verificar youtubeApiKeys (WordPress) 392 if (typeof window.youtubeApiKeys !== 'undefined' && window.youtubeApiKeys && Array.isArray(window.youtubeApiKeys) && window.youtubeApiKeys.length > 0) { 393 const index = window.currentApiKeyIndex || 0; 394 if (index < window.youtubeApiKeys.length && window.youtubeApiKeys[index]) { 395 console.log('Retornando chave do youtubeApiKeys:', window.youtubeApiKeys[index].substring(0, 10) + '...'); 396 return window.youtubeApiKeys[index]; 397 } 398 } 399 400 // Verificar localStorage como fallback 401 const localKey = localStorage.getItem('youtubeApiKey'); 402 if (localKey && localKey.trim() !== '' && localKey !== 'null') { 403 console.log('Retornando chave do localStorage:', localKey.substring(0, 10) + '...'); 404 return localKey; 405 } 406 407 const localKeys = localStorage.getItem('youtubeApiKeys'); 408 if (localKeys && localKeys !== 'null') { 409 try { 410 const parsedKeys = JSON.parse(localKeys); 411 if (Array.isArray(parsedKeys) && parsedKeys.length > 0 && parsedKeys[0]) { 412 console.log('Retornando primeira chave do localStorage array'); 413 return parsedKeys[0]; 414 } 415 } catch (e) { 416 console.error('Erro ao parsear youtubeApiKeys do localStorage:', e); 417 } 418 } 419 420 console.error('Nenhuma chave API válida encontrada!'); 421 return null; 422}; 423 424window.switchToNextApiKey = function() { 425 if (typeof youtubeApiKeys === 'undefined' || !youtubeApiKeys || youtubeApiKeys.length <= 1) { 426 return false; // Não há outras chaves disponÃveis 427 } 428 429 if (typeof window.currentApiKeyIndex === 'undefined') { 430 window.currentApiKeyIndex = 0; 431 } 432 433 const oldIndex = window.currentApiKeyIndex; 434 window.currentApiKeyIndex = (window.currentApiKeyIndex + 1) % youtubeApiKeys.length; 435 436 if (oldIndex !== window.currentApiKeyIndex) { 437 if (typeof updateApiKeyUI === 'function') { 438 updateApiKeyUI(); 439 } 440 if (typeof showNotification === 'function') { 441 showNotification('Alternado para próxima chave de API (limite de quota atingido)'); 442 } 443 return true; 444 } 445 446 return false;
447}; 448 449// Inicializar youtubeApiKeys se não existir 450if (typeof window.youtubeApiKeys === 'undefined') { 451 window.youtubeApiKeys = []; 452 window.currentApiKeyIndex = 0; 453} 454 455// Verificar disponibilidade de youtube_analyzer_data 456if (typeof window.youtube_analyzer_data === 'undefined') { 457 window.youtube_analyzer_data = { 458 rest_url: '/wp-json/youtube-analyzer/v1/', 459 nonce: '', 460 user_id: '1', 461 is_admin: 'yes' 462 }; 463 console.warn('Dados da API do WordPress não encontrados. Usando valores padrão.'); 464}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.