PluginProbe ʕ •ᴥ•ʔ
Custom Twitter Feeds – A Tweets Widget or X Feed Widget / 2.8.0
Custom Twitter Feeds – A Tweets Widget or X Feed Widget v2.8.0
2.8.0 2.7.0 2.6.1 2.6.0 1.0 1.0.1 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.2 1.2.1 1.2.10 1.2.11 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3 1.4 1.4.1 1.5 1.5.1 1.6 1.6.1 1.7 1.8 1.8.1 1.8.2 1.8.3 1.8.4 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1 2.1.1 2.1.2 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.5.4 2.5.5 trunk
custom-twitter-feeds / admin / assets / js / settings.js
custom-twitter-feeds / admin / assets / js Last commit date
about.js 4 weeks ago admin-notifications.js 4 weeks ago settings.js 4 weeks ago smash-usage-session.js 4 weeks ago support.js 4 weeks ago
settings.js
1234 lines
1 var ctfSettings;
2
3 // Declaring as global variable for quick prototyping
4 var settings_data = {
5 adminUrl: ctf_settings.admin_url,
6 nonce: ctf_settings.nonce,
7 ajaxHandler: ctf_settings.ajax_handler,
8 model: ctf_settings.model,
9 feeds: ctf_settings.feeds,
10 links: ctf_settings.links,
11 tooltipName: null,
12 sourcesList : ctf_settings.sources,
13 dialogBoxPopupScreen : ctf_settings.dialogBoxPopupScreen,
14 selectSourceScreen : ctf_settings.selectSourceScreen,
15 ctfRebrand : ctf_settings.ctfRebrand,
16 socialWallActivated: ctf_settings.socialWallActivated,
17 socialWallLinks: ctf_settings.socialWallLinks,
18 exportFeed: 'none',
19 locales: ctf_settings.locales,
20 timezones: ctf_settings.timezones,
21 genericText: ctf_settings.genericText,
22 generalTab: ctf_settings.generalTab,
23 feedsTab: ctf_settings.feedsTab,
24 translationTab: ctf_settings.translationTab,
25 advancedTab: ctf_settings.advancedTab,
26 footerUpgradeUrl: ctf_settings.footerUpgradeUrl,
27 upgradeUrl: ctf_settings.upgradeUrl,
28 supportPageUrl: ctf_settings.supportPageUrl,
29 isDevSite: ctf_settings.isDevSite,
30 licenseKey: ctf_settings.licenseKey,
31 pluginItemName: ctf_settings.pluginItemName,
32 licenseType: 'free',
33 licenseStatus: ctf_settings.licenseStatus,
34 licenseErrorMsg: ctf_settings.licenseErrorMsg,
35 extensionsLicense: ctf_settings.extensionsLicense,
36 extensionsLicenseKey: ctf_settings.extensionsLicenseKey,
37 extensionFieldHasError: false,
38 cronNextCheck: ctf_settings.nextCheck,
39 currentView: null,
40 selected: null,
41 current: 0,
42 sections: ["General", "Feeds", "Translation", "Advanced"],
43 indicator_width: 0,
44 indicator_pos: 0,
45 forwards: true,
46 currentTab: null,
47 import_file: null,
48 gdprInfoTooltip: null,
49 loaderSVG: ctf_settings.loaderSVG,
50 checkmarkSVG: ctf_settings.checkmarkSVG,
51 uploadSVG: ctf_settings.uploadSVG,
52 exportSVG: ctf_settings.exportSVG,
53 reloadSVG: ctf_settings.reloadSVG,
54 tooltipHelpSvg: ctf_settings.tooltipHelpSvg,
55 tooltip : {
56 text : '',
57 hover : false
58 },
59
60 cogSVG: ctf_settings.cogSVG,
61 deleteSVG: ctf_settings.deleteSVG,
62 svgIcons : ctf_settings.svgIcons,
63 accountDetails : ctf_settings.accountDetails,
64 newAccountData : ctf_settings.newAccountData,
65
66
67 appCredentials : ctf_settings.appCredentials,
68 connectAccountScreen : ctf_settings.connectAccountScreen,
69 appOAUTH : ctf_settings.appOAUTH,
70 testConnectionStatus: null,
71 recheckLicenseStatus: null,
72 btnStatus: null,
73 uploadStatus: null,
74 clearCacheStatus: null,
75 optimizeCacheStatus: null,
76 persistentCacheStatus: null,
77 twittercardCacheStatus: null,
78
79 dpaResetStatus: null,
80 pressedBtnName: null,
81 loading: false,
82 hasError: ctf_settings.hasError,
83 manualAccountResp : false,
84
85 dialogBox : {
86 active : false,
87 type : null,
88 heading : null,
89 description : null,
90 customButtons : undefined
91 },
92 sourceToDelete : {},
93 viewsActive : {
94 sourcePopup : false,
95 sourcePopupScreen : 'redirect_1',
96 sourcePopupType : 'creation',
97 instanceSourceActive : null,
98 connectAccountPopup : false,
99 connectAccountStep : 'step_1',
100 accountDetailsActive : false,
101 appDetailsActive : false,
102 },
103 //Add New Source
104 newSourceData : ctf_settings.newSourceData ? ctf_settings.newSourceData : null,
105 sourceConnectionURLs : ctf_settings.sourceConnectionURLs,
106 returnedApiSourcesList : [],
107 addNewSource : {
108 typeSelected : 'page',
109 manualSourceID : null,
110 manualSourceToken : null
111 },
112 selectedFeed : 'none',
113 expandedFeedID : null,
114 notificationElement : {
115 type : 'success', // success, error, warning, message
116 text : '',
117 shown : null
118 },
119 selectedSourcesToConnect : [],
120
121 //Loading Bar
122 fullScreenLoader : false,
123 appLoaded : false,
124 previewLoaded : false,
125 loadingBar : true,
126 loadingAjax : false,
127
128 notificationElement : {
129 type : 'success', // success, error, warning, message
130 text : '',
131 shown : null
132 }
133 };
134
135 // The tab component
136 Vue.component("tab", {
137 props: ["section", "index"],
138 template: `
139 <button type="button" class="tab" :id="'ctf-settings-tab-' + section.toLowerCase().trim()" role="tab" :aria-selected="section === $parent.currentTab ? 'true' : 'false'" :aria-controls="'ctf-panel-' + section.toLowerCase().trim()" :tabindex="section === $parent.currentTab ? 0 : -1" @click="emitWidth($el);changeComponent(index);activeTab(section)" @keydown="onTabKeydown">{{section}}</button>
140 `,
141 created: () => {
142 let urlParams = new URLSearchParams(window.location.search);
143 let view = urlParams.get('view');
144 if ( view === null ) {
145 view = 'general';
146 }
147 settings_data.currentView = view;
148 settings_data.currentTab = settings_data.sections[0];
149 settings_data.selected = "app-1";
150 },
151 methods: {
152
153
154 emitWidth: function(el) {
155 settings_data.indicator_width = jQuery(el).outerWidth();
156 settings_data.indicator_pos = jQuery(el).position().left;
157 },
158 changeComponent: function(index) {
159 var prev = settings_data.current;
160 if (prev < index) {
161 settings_data.forwards = false;
162 } else if (prev > index) {
163 settings_data.forwards = true;
164 }
165 settings_data.selected = "app-" + (index + 1);
166 settings_data.current = index;
167 },
168 activeTab: function(section) {
169 this.setView(section.toLowerCase().trim());
170 settings_data.currentTab = section;
171 },
172 setView: function(section) {
173 history.replaceState({}, null, settings_data.adminUrl + 'admin.php?page=ctf-settings&view=' + section);
174 },
175 // WAI-ARIA Authoring Practices tablist keyboard interaction (ports IG settings tabs).
176 onTabKeydown: function(e) {
177 var tabs = Array.prototype.slice.call(
178 document.querySelectorAll('#ctf-settings [role="tablist"] [role="tab"]')
179 );
180 var idx = tabs.indexOf(e.currentTarget);
181 if (idx === -1) return;
182 var next = null;
183 if (e.key === 'ArrowRight' || e.keyCode === 39) {
184 next = tabs[(idx + 1) % tabs.length];
185 } else if (e.key === 'ArrowLeft' || e.keyCode === 37) {
186 next = tabs[(idx - 1 + tabs.length) % tabs.length];
187 } else if (e.key === 'Home' || e.keyCode === 36) {
188 next = tabs[0];
189 } else if (e.key === 'End' || e.keyCode === 35) {
190 next = tabs[tabs.length - 1];
191 }
192 if (!next) return;
193 e.preventDefault();
194 next.focus();
195 next.click();
196 }
197 }
198 });
199
200 var ctfSettings = new Vue({
201 el: "#ctf-settings",
202 http: {
203 emulateJSON: true,
204 emulateHTTP: true
205 },
206 data: settings_data,
207 created: function() {
208 this.$nextTick(function() {
209 let tabEl = document.querySelector('.tab');
210 settings_data.indicator_width = tabEl.offsetWidth;
211 });
212 setTimeout(function(){
213 settings_data.appLoaded = true;
214 },350);
215 },
216 mounted: function(){
217 var self = this;
218 // set the current view page on page load
219 let activeEl = document.querySelector('button.tab#ctf-settings-tab-' + settings_data.currentView);
220 // SMASH-1378: bail out if the tab for the current ?view= param does not
221 // exist (e.g. an invalid/mistyped view) so we do not dereference null on
222 // activeEl.offsetWidth below and crash the settings UI bootstrap.
223 if ( ! activeEl ) { return; }
224 // we have to uppercase the first letter
225 let currentView = settings_data.currentView.charAt(0).toUpperCase() + settings_data.currentView.slice(1);
226 let viewIndex = settings_data.sections.indexOf(currentView) + 1;
227 settings_data.indicator_width = activeEl.offsetWidth;
228 settings_data.indicator_pos = activeEl.offsetLeft;
229 settings_data.selected = "app-" + viewIndex;
230 settings_data.current = viewIndex;
231 settings_data.currentTab = currentView;
232
233 setTimeout(function(){
234 settings_data.appLoaded = true;
235 },350);
236
237 },
238 computed: {
239 getStyle: function() {
240 return {
241 position: "absolute",
242 bottom: "0px",
243 left: settings_data.indicator_pos + "px",
244 width: settings_data.indicator_width + "px",
245 height: "2px"
246 };
247 },
248 chooseDirection: function() {
249 if (settings_data.forwards == true) {
250 return "slide-fade";
251 } else {
252 return "slide-fade";
253 }
254 }
255 },
256 methods: {
257 activateLicense: function() {
258 if (this.licenseType === 'free') {
259 this.runOneClickUpgrade();
260 } else {
261 this.activateProLicense();
262 }
263 },
264 activateProLicense: function() {
265 this.hasError = false;
266 this.loading = true;
267 this.pressedBtnName = 'ctf';
268
269 let data = new FormData();
270 data.append( 'action', 'ctf_activate_license' );
271 data.append( 'license_key', this.licenseKey );
272 data.append( 'nonce', this.nonce );
273 fetch(this.ajaxHandler, {
274 method: "POST",
275 credentials: 'same-origin',
276 body: data
277 })
278 .then(response => response.json())
279 .then(data => {
280 if ( data.success == false ) {
281 this.licenseStatus = 'inactive';
282 this.hasError = true;
283 this.loading = false;
284 return;
285 }
286 if ( data.success == true ) {
287 let licenseData = data.data.licenseData;
288 this.licenseStatus = data.data.licenseStatus;
289 this.loading = false;
290 this.pressedBtnName = null;
291
292 if (
293 data.data.licenseStatus == 'inactive' ||
294 data.data.licenseStatus == 'invalid' ||
295 data.data.licenseStatus == 'expired'
296 ) {
297 this.hasError = true;
298 if( licenseData.error ) {
299 this.licenseErrorMsg = licenseData.errorMsg
300 }
301 }
302 }
303 return;
304 });
305 },
306 deactivateLicense: function() {
307 this.loading = true;
308 this.pressedBtnName = 'ctf';
309 let data = new FormData();
310 data.append( 'action', 'ctf_deactivate_license' );
311 data.append( 'nonce', this.nonce );
312 fetch(this.ajaxHandler, {
313 method: "POST",
314 credentials: 'same-origin',
315 body: data
316 })
317 .then(response => response.json())
318 .then(data => {
319 if ( data.success == true ) {
320 this.licenseStatus = data.data.licenseStatus ;
321 this.loading = false;
322 this.pressedBtnName = null;
323 }
324 return;
325 });
326 },
327 licenseActiveAction: function(extension) {
328 extension = typeof extension !== 'undefined' ? extension : false;
329 if (this.licenseType === 'free') {
330 this.runOneClickUpgrade();
331 } else {
332 if (typeof extension !== 'undefined') {
333 this.deactivateExtensionLicense(extension);
334 } else {
335 this.deactivateLicense();
336 }
337 }
338
339 },
340
341 runOneClickUpgrade: function() {
342 this.hasError = false;
343 this.loading = true;
344 this.pressedBtnName = 'ctf';
345
346 let data = new FormData();
347 data.append( 'action', 'ctf_maybe_upgrade_redirect' );
348 data.append( 'license_key', this.licenseKey );
349 data.append( 'nonce', this.nonce );
350 fetch(this.ajaxHandler, {
351 method: "POST",
352 credentials: 'same-origin',
353 body: data
354 })
355 .then(response => response.json())
356 .then(data => {
357 if ( data.success === false ) {
358 this.licenseStatus = 'invalid';
359 this.hasError = true;
360 this.loading = false;
361 if( typeof data.data !== 'undefined' ) {
362 this.licenseErrorMsg = data.data.message
363 }
364 return;
365 }
366 if ( data.success === true ) {
367 window.location.href = data.data.url
368 }
369 return;
370 });
371 },
372
373 /**
374 * Activate Extensions License
375 *
376 * @since 2.0
377 *
378 * @param {object} extension
379 */
380 activateExtensionLicense: function( extension ) {
381 let licenseKey = this.extensionsLicenseKey[extension.name];
382 this.extensionFieldHasError = false;
383 this.loading = true;
384 this.pressedBtnName = extension.name;
385 if ( ! licenseKey ) {
386 this.loading = false;
387 this.extensionFieldHasError = true;
388 return;
389 }
390 let data = new FormData();
391 data.append( 'action', 'ctf_activate_extension_license' );
392 data.append( 'license_key', licenseKey );
393 data.append( 'extension_name', extension.name );
394 data.append( 'extension_item_name', extension.itemName );
395 data.append( 'nonce', this.nonce );
396 fetch(this.ajaxHandler, {
397 method: "POST",
398 credentials: 'same-origin',
399 body: data
400 })
401 .then(response => response.json())
402 .then(data => {
403 this.loading = false;
404 if ( data.success == true ) {
405 this.extensionFieldHasError = false;
406 this.pressedBtnName = null;
407 if ( data.data.licenseStatus == 'invalid' ) {
408 this.extensionFieldHasError = true;
409 this.notificationElement = {
410 type : 'error',
411 text : this.genericText.invalidLicenseKey,
412 shown : "shown"
413 };
414 }
415 if ( data.data.licenseStatus == 'valid' ) {
416 this.notificationElement = {
417 type : 'success',
418 text : this.genericText.licenseActivated,
419 shown : "shown"
420 };
421 }
422 extension.licenseStatus = data.data.licenseStatus;
423 extension.licenseKey = licenseKey;
424
425 setTimeout(function(){
426 this.notificationElement.shown = "hidden";
427 }.bind(this), 3000);
428 }
429 return;
430 });
431 },
432
433 /**
434 * Deactivate Extensions License
435 *
436 * @since 2.0
437 *
438 * @param {object} extension
439 */
440 deactivateExtensionLicense: function( extension ) {
441 let licenseKey = this.extensionsLicenseKey[extension.name];
442 this.extensionFieldHasError = false;
443 this.loading = true;
444 this.pressedBtnName = extension.name;
445 let data = new FormData();
446 data.append( 'action', 'ctf_deactivate_extension_license' );
447 data.append( 'extension_name', extension.name );
448 data.append( 'extension_item_name', extension.itemName );
449 data.append( 'nonce', this.nonce );
450 fetch(this.ajaxHandler, {
451 method: "POST",
452 credentials: 'same-origin',
453 body: data
454 })
455 .then(response => response.json())
456 .then(data => {
457 this.loading = false;
458 if ( data.success == true ) {
459 this.extensionFieldHasError = false;
460 this.pressedBtnName = null;
461 if ( data.data.licenseStatus == 'deactivated' ) {
462 this.notificationElement = {
463 type : 'success',
464 text : this.genericText.licenseDeactivated,
465 shown : "shown"
466 };
467 }
468 extension.licenseStatus = data.data.licenseStatus;
469 extension.licenseKey = licenseKey;
470
471 setTimeout(function(){
472 this.notificationElement.shown = "hidden";
473 }.bind(this), 3000);
474 }
475 return;
476 });
477 },
478 testConnection: function() {
479 this.testConnectionStatus = 'loading';
480 let data = new FormData();
481 data.append( 'action', 'ctf_test_connection' );
482 data.append( 'nonce', this.nonce );
483 fetch(this.ajaxHandler, {
484 method: "POST",
485 credentials: 'same-origin',
486 body: data
487 })
488 .then(response => response.json())
489 .then(data => {
490 if ( data.success == false ) {
491 this.testConnectionStatus = 'error';
492 }
493 if ( data.success == true ) {
494 this.testConnectionStatus = 'success';
495
496 setTimeout(function() {
497 this.testConnectionStatus = null;
498 }.bind(this), 3000);
499 }
500 return;
501 });
502 },
503 recheckLicense: function( licenseKey, itemName, optionName = null ) {
504 this.recheckLicenseStatus = 'loading';
505 this.pressedBtnName = optionName;
506 let data = new FormData();
507 data.append( 'action', 'ctf_recheck_connection' );
508 data.append( 'license_key', licenseKey );
509 data.append( 'item_name', itemName );
510 data.append( 'option_name', optionName );
511 data.append( 'nonce', this.nonce );
512 fetch(this.ajaxHandler, {
513 method: "POST",
514 credentials: 'same-origin',
515 body: data
516 })
517 .then(response => response.json())
518 .then(data => {
519 if ( data.success == true ) {
520 if ( data.data.license == 'valid' ) {
521 this.recheckLicenseStatus = 'success';
522 }
523 if ( data.data.license == 'expired' ) {
524 this.recheckLicenseStatus = 'error';
525 }
526
527 // if the api license status has changed from old stored license status
528 // then reload the page to show proper error message and notices
529 // or hide error messages and notices
530 if ( data.data.licenseChanged == true ) {
531 location.reload();
532 }
533
534 setTimeout(function() {
535 this.pressedBtnName = null;
536 this.recheckLicenseStatus = null;
537 }.bind(this), 3000);
538 }
539 return;
540 });
541 },
542 recheckLicenseIcon: function() {
543 if ( this.recheckLicenseStatus == null ) {
544 return this.generalTab.licenseBox.recheckLicense;
545 } else if ( this.recheckLicenseStatus == 'loading' ) {
546 return this.loaderSVG;
547 } else if ( this.recheckLicenseStatus == 'success' ) {
548 return '<i class="fa fa-check-circle"></i> ' + this.generalTab.licenseBox.licenseValid;
549 } else if ( this.recheckLicenseStatus == 'error' ) {
550 return '<i class="fa fa-times-circle"></i> ' + this.generalTab.licenseBox.licenseExpired;
551 }
552 },
553 recheckBtnText: function( btnName ) {
554 if ( this.recheckLicenseStatus == null || this.pressedBtnName != btnName ) {
555 return this.generalTab.licenseBox.recheckLicense;
556 } else if ( this.recheckLicenseStatus == 'loading' && this.pressedBtnName == btnName ) {
557 return this.loaderSVG;
558 } else if ( this.recheckLicenseStatus == 'success' ) {
559 return '<i class="fa fa-check-circle"></i> ' + this.generalTab.licenseBox.licenseValid;
560 } else if ( this.recheckLicenseStatus == 'error' ) {
561 return '<i class="fa fa-times-circle"></i> ' + this.generalTab.licenseBox.licenseExpired;
562 }
563 },
564 testConnectionIcon: function() {
565 if ( this.testConnectionStatus == 'loading' ) {
566 return this.loaderSVG;
567 } else if ( this.testConnectionStatus == 'success' ) {
568 return '<i class="fa fa-check-circle"></i> ' + this.generalTab.licenseBox.connectionSuccessful;
569 } else if ( this.testConnectionStatus == 'error' ) {
570 return `<i class="fa fa-times-circle"></i> ${this.generalTab.licenseBox.connectionFailed} <a href="#">${this.generalTab.licenseBox.viewError}</a>`;
571 }
572 },
573 importFile: function() {
574 document.getElementById("import_file").click();
575 },
576 uploadFile: function( event ) {
577 this.uploadStatus = 'loading';
578 let file = this.$refs.file.files[0];
579 let data = new FormData();
580 data.append( 'action', 'ctf_import_settings_json' );
581 data.append( 'file', file );
582 data.append( 'nonce', this.nonce );
583 fetch(this.ajaxHandler, {
584 method: "POST",
585 credentials: 'same-origin',
586 body: data
587 })
588 .then(response => response.json())
589 .then(data => {
590 this.uploadStatus = null;
591 this.$refs.file.files[0] = null;
592 if ( data.success == false ) {
593 this.notificationElement = {
594 type : 'error',
595 text : this.genericText.failedToImportFeed,
596 shown : "shown"
597 };
598 }
599 if ( data.success == true ) {
600 this.feeds = data.data.feeds;
601 this.notificationElement = {
602 type : 'success',
603 text : this.genericText.feedImported,
604 shown : "shown"
605 };
606 }
607 setTimeout(function(){
608 this.notificationElement.shown = "hidden";
609 }.bind(this), 3000);
610 });
611 },
612 exportFeedSettings: function() {
613 // return if no feed is selected
614 if ( this.exportFeed === 'none' ) {
615 return;
616 }
617
618 let url = this.ajaxHandler + '?action=ctf_export_settings_json&feed_id=' + this.exportFeed;
619 window.location = url;
620 },
621 saveSettings: function() {
622 this.btnStatus = 'loading';
623 this.pressedBtnName = 'saveChanges';
624 let data = new FormData();
625 data.append( 'action', 'ctf_save_settings' );
626 data.append( 'model', JSON.stringify( this.model ) );
627 data.append( 'ctf_license_key', this.licenseKey );
628 data.append( 'extensions_license_key', JSON.stringify( this.extensionsLicenseKey ) );
629 data.append( 'nonce', this.nonce );
630 fetch(this.ajaxHandler, {
631 method: "POST",
632 credentials: 'same-origin',
633 body: data
634 })
635 .then(response => response.json())
636 .then(data => {
637 if ( data.success == false ) {
638 this.btnStatus = 'error';
639 return;
640 }
641
642 this.cronNextCheck = data.data.cronNextCheck;
643 this.btnStatus = 'success';
644 setTimeout(function() {
645 this.btnStatus = null;
646 this.pressedBtnName = null;
647 }.bind(this), 3000);
648 });
649 },
650 clearCache: function() {
651 this.clearCacheStatus = 'loading';
652 let data = new FormData();
653 data.append( 'action', 'ctf_clear_cache_settings' );
654 data.append( 'model', JSON.stringify( this.model ) );
655 data.append( 'nonce', this.nonce );
656 fetch(this.ajaxHandler, {
657 method: "POST",
658 credentials: 'same-origin',
659 body: data
660 })
661 .then(response => response.json())
662 .then(data => {
663 if ( data.success == false ) {
664 this.clearCacheStatus = 'error';
665 return;
666 }
667 this.cronNextCheck = data.data.cronNextCheck;
668 this.clearCacheStatus = 'success';
669 setTimeout(function() {
670 this.clearCacheStatus = null;
671 }.bind(this), 3000);
672 });
673 },
674 showTooltip: function( tooltipName ) {
675 this.tooltipName = tooltipName;
676 },
677 hideTooltip: function() {
678 this.tooltipName = null;
679 },
680 gdprOptions: function() {
681 this.gdprInfoTooltip = null;
682 },
683 gdprLimited: function() {
684 this.gdprInfoTooltip = this.gdprInfoTooltip == null ? true : null;
685 },
686 clearImageResizeCache: function() {
687 this.optimizeCacheStatus = 'loading';
688 let data = new FormData();
689 data.append( 'action', 'ctf_clear_image_resize_cache' );
690 data.append( 'nonce', this.nonce );
691 fetch(this.ajaxHandler, {
692 method: "POST",
693 credentials: 'same-origin',
694 body: data
695 })
696 .then(response => response.json())
697 .then(data => {
698 if ( data.success == false ) {
699 this.optimizeCacheStatus = 'error';
700 return;
701 }
702 this.optimizeCacheStatus = 'success';
703 setTimeout(function() {
704 this.optimizeCacheStatus = null;
705 }.bind(this), 3000);
706 });
707 },
708 clearPersistentCache: function() {
709 this.persistentCacheStatus = 'loading';
710 let data = new FormData();
711 data.append( 'action', 'ctf_clear_persistent_cache' );
712 data.append( 'nonce', this.nonce );
713 fetch(this.ajaxHandler, {
714 method: "POST",
715 credentials: 'same-origin',
716 body: data
717 })
718 .then(response => response.json())
719 .then(data => {
720 if ( data.success == false ) {
721 this.persistentCacheStatus = 'error';
722 return;
723 }
724 this.persistentCacheStatus = 'success';
725 setTimeout(function() {
726 this.persistentCacheStatus = null;
727 }.bind(this), 3000);
728 });
729 },
730 clearTwittercardCache: function() {
731 this.twittercardCacheStatus = 'loading';
732 let data = new FormData();
733 data.append( 'action', 'ctf_clear_twittercard_cache' );
734 data.append( 'nonce', this.nonce );
735 fetch(this.ajaxHandler, {
736 method: "POST",
737 credentials: 'same-origin',
738 body: data
739 })
740 .then(response => response.json())
741 .then(data => {
742 if ( data.success == false ) {
743 this.twittercardCacheStatus = 'error';
744 return;
745 }
746 this.twittercardCacheStatus = 'success';
747 setTimeout(function() {
748 this.twittercardCacheStatus = null;
749 }.bind(this), 3000);
750 });
751 },
752 dpaReset: function() {
753 this.dpaResetStatus = 'loading';
754 let data = new FormData();
755 data.append( 'action', 'ctf_dpa_reset' );
756 data.append( 'nonce', this.nonce );
757 fetch(this.ajaxHandler, {
758 method: "POST",
759 credentials: 'same-origin',
760 body: data
761 })
762 .then(response => response.json())
763 .then(data => {
764 if ( data.success == false ) {
765 this.dpaResetStatus = 'error';
766 return;
767 }
768 this.dpaResetStatus = 'success';
769 setTimeout(function() {
770 this.dpaResetStatus = null;
771 }.bind(this), 3000);
772 });
773 },
774 saveChangesIcon: function() {
775 if ( this.btnStatus == 'loading' ) {
776 return this.loaderSVG;
777 } else if ( this.btnStatus == 'success' ) {
778 return this.checkmarkSVG;
779 } else if ( this.btnStatus == 'error' ) {
780 return `<i class="fa fa-times-circle"></i>`;
781 }
782 },
783 importBtnIcon: function() {
784 if ( this.uploadStatus === null ) {
785 return this.uploadSVG;
786 }
787 if ( this.uploadStatus == 'loading' ) {
788 return this.loaderSVG;
789 } else if ( this.uploadStatus == 'success' ) {
790 return this.checkmarkSVG;
791 } else if ( this.uploadStatus == 'error' ) {
792 return `<i class="fa fa-times-circle"></i>`;
793 }
794 },
795 clearCacheIcon: function() {
796 if ( this.clearCacheStatus === null ) {
797 return this.reloadSVG;
798 }
799 if ( this.clearCacheStatus == 'loading' ) {
800 return this.loaderSVG;
801 } else if ( this.clearCacheStatus == 'success' ) {
802 return this.checkmarkSVG;
803 } else if ( this.clearCacheStatus == 'error' ) {
804 return `<i class="fa fa-times-circle"></i>`;
805 }
806 },
807 clearImageResizeCacheIcon: function() {
808 if ( this.optimizeCacheStatus === null ) {
809 return;
810 }
811 if ( this.optimizeCacheStatus == 'loading' ) {
812 return this.loaderSVG;
813 } else if ( this.optimizeCacheStatus == 'success' ) {
814 return this.checkmarkSVG;
815 } else if ( this.optimizeCacheStatus == 'error' ) {
816 return `<i class="fa fa-times-circle"></i>`;
817 }
818 },
819 clearPersistentCacheIcon: function() {
820 if ( this.persistentCacheStatus === null ) {
821 return;
822 }
823 if ( this.persistentCacheStatus == 'loading' ) {
824 return this.loaderSVG;
825 } else if ( this.persistentCacheStatus == 'success' ) {
826 return this.checkmarkSVG;
827 } else if ( this.persistentCacheStatus == 'error' ) {
828 return `<i class="fa fa-times-circle"></i>`;
829 }
830 },
831 clearTwittercardCacheIcon: function() {
832 if ( this.twittercardCacheStatus === null ) {
833 return;
834 }
835 if ( this.twittercardCacheStatus == 'loading' ) {
836 return this.loaderSVG;
837 } else if ( this.twittercardCacheStatus == 'success' ) {
838 return this.checkmarkSVG;
839 } else if ( this.twittercardCacheStatus == 'error' ) {
840 return `<i class="fa fa-times-circle"></i>`;
841 }
842 },
843
844 dpaResetStatusIcon: function() {
845 if ( this.dpaResetStatus === null ) {
846 return;
847 }
848 if ( this.dpaResetStatus == 'loading' ) {
849 return this.loaderSVG;
850 } else if ( this.dpaResetStatus == 'success' ) {
851 return this.checkmarkSVG;
852 } else if ( this.dpaResetStatus == 'error' ) {
853 return `<i class="fa fa-times-circle"></i>`;
854 }
855 },
856
857 printUsedInText: function( usedInNumber ){
858 if(usedInNumber == 0){
859 return this.genericText.sourceNotUsedYet;
860 }
861 return this.genericText.usedIn + ' ' + usedInNumber + ' ' +(usedInNumber == 1 ? this.genericText.feed : this.genericText.feeds);
862 },
863
864 /**
865 * Delete Source Ajax
866 *
867 * @since 2.0
868 */
869 deleteSource : function(sourceToDelete){
870 var self = this;
871 let data = new FormData();
872 data.append( 'action', 'ctf_feed_saver_manager_delete_source' );
873 data.append( 'source_id', sourceToDelete.id);
874 data.append( 'nonce', this.nonce );
875 fetch(self.ajaxHandler, {
876 method: "POST",
877 credentials: 'same-origin',
878 body: data
879 })
880 .then(response => response.json())
881 .then(data => {
882 if (sourceToDelete.just_added) {
883 window.location.href = window.location.href.replace('ctf_access_token','ctf_null');
884 }
885 self.sourcesList = data;
886 });
887 },
888
889 /**
890 * Check if Value is Empty
891 *
892 * @since 2.0
893 *
894 * @return boolean
895 */
896 checkNotEmpty : function(value){
897 return value != null && value.replace(/ /gi,'') != '';
898 },
899
900 /**
901 * Activate View
902 *
903 * @since 2.0
904 */
905 activateView : function(viewName, sourcePopupType = 'creation', ajaxAction = false){
906 var self = this;
907 self.viewsActive[viewName] = (self.viewsActive[viewName] == false ) ? true : false;
908 if(viewName == 'sourcePopup' && sourcePopupType == 'creationRedirect'){
909 setTimeout(function(){
910 self.$refs.addSourceRef.processIFConnect()
911 },3500);
912 }
913
914 },
915
916 /**
917 * Switch & Change Feed Screens
918 *
919 * @since 2.0
920 */
921 switchScreen: function(screenType, screenName){
922 this.viewsActive[screenType] = screenName;
923 },
924
925 /**
926 * Parse JSON
927 *
928 * @since 2.0
929 *
930 * @return jsonObject / Boolean
931 */
932 jsonParse : function(jsonString){
933 try {
934 return JSON.parse(jsonString);
935 } catch(e) {
936 return false;
937 }
938 },
939
940
941 /**
942 * Ajax Post Action
943 *
944 * @since 2.0
945 */
946 ajaxPost : function(data, callback){
947 var self = this;
948 self.$http.post(self.ajaxHandler,data).then(callback);
949 },
950
951 /**
952 * Check if Object has Nested Property
953 *
954 * @since 2.0
955 *
956 * @return boolean
957 */
958 hasOwnNestedProperty : function(obj,propertyPath) {
959 if (!propertyPath){return false;}var properties = propertyPath.split('.');
960 for (var i = 0; i < properties.length; i++) {
961 var prop = properties[i];
962 if (!obj || !obj.hasOwnProperty(prop)) {
963 return false;
964 } else {
965 obj = obj[prop];
966 }
967 }
968 return true;
969 },
970
971 /**
972 * Show Tooltip on Hover
973 *
974 * @since 2.0
975 */
976 toggleElementTooltip : function(tooltipText, type, align = 'center', event){
977 var self = this,
978 target = (event && event.currentTarget) || (window.event && window.event.currentTarget),
979 tooltip = (target != undefined && target != null) ? document.querySelector('.sb-control-elem-tltp-content') : null;
980 if(tooltip != null && type == 'show'){
981 self.tooltip.text = tooltipText;
982 var position = target.getBoundingClientRect(),
983 left = position.left + 10,
984 top = position.top - 10;
985 tooltip.style.left = left + 'px';
986 tooltip.style.top = top + 'px';
987 tooltip.style.textAlign = align;
988 self.tooltip.hover = true;
989 }
990 if(type == 'hide'){
991 self.tooltip.hover = false;
992 }
993 },
994
995 /**
996 * Hover Tooltip
997 *
998 * @since 2.0
999 */
1000 hoverTooltip : function(type){
1001 this.tooltip.hover = type;
1002 },
1003
1004 /**
1005 * Open Dialog Box
1006 *
1007 * @since 2.0
1008 */
1009 openDialogBox : function(type, args = []){
1010 var self = this,
1011 heading = self.dialogBoxPopupScreen[type].heading,
1012 description = self.dialogBoxPopupScreen[type].description,
1013 customButtons = self.dialogBoxPopupScreen[type].customButtons;
1014
1015
1016 switch (type) {
1017 case "deleteSource":
1018 self.sourceToDelete = args;
1019 heading = heading.replace("#", self.sourceToDelete.username);
1020 break;
1021 }
1022 self.dialogBox = {
1023 active : true,
1024 type : type,
1025 heading : heading,
1026 description : description,
1027 customButtons : customButtons
1028 };
1029 },
1030
1031
1032 /**
1033 * Confirm Dialog Box Actions
1034 *
1035 * @since 2.0
1036 */
1037 confirmDialogAction : function(){
1038 var self = this;
1039 switch (self.dialogBox.type) {
1040 case 'deleteSource':
1041 self.deleteSource(self.sourceToDelete);
1042 break;
1043 case 'deleteAccount':
1044 self.deleteAccount();
1045 break;
1046 case 'deleteApp':
1047 self.deleteAccount(true);
1048 break;
1049 }
1050 },
1051
1052 /**
1053 * Display Feed Sources Settings
1054 *
1055 * @since 2.0
1056 *
1057 * @param {object} source
1058 * @param {int} sourceIndex
1059 */
1060 displayFeedSettings: function(source, sourceIndex) {
1061 this.expandedFeedID = sourceIndex + 1;
1062 },
1063
1064 /**
1065 * Hide Feed Sources Settings
1066 *
1067 * @since 2.0
1068 *
1069 * @param {object} source
1070 * @param {int} sourceIndex
1071 */
1072 hideFeedSettings: function() {
1073 this.expandedFeedID = null;
1074 },
1075
1076 /**
1077 * Copy text to clipboard
1078 *
1079 * @since 2.0
1080 */
1081 copyToClipBoard : function(value){
1082 var self = this;
1083 const el = document.createElement('textarea');
1084 el.className = 'ctf-fb-cp-clpboard';
1085 el.value = value;
1086 document.body.appendChild(el);
1087 el.select();
1088 document.execCommand('copy');
1089 document.body.removeChild(el);
1090 self.notificationElement = {
1091 type : 'success',
1092 text : this.genericText.copiedClipboard,
1093 shown : "shown"
1094 };
1095 setTimeout(function(){
1096 self.notificationElement.shown = "hidden";
1097 }, 3000);
1098 },
1099
1100
1101 /**
1102 * View Source Instances
1103 *
1104 * @since 2.0
1105 */
1106 viewSourceInstances : function(source){
1107 var self = this;
1108 self.viewsActive.instanceSourceActive = source;
1109 },
1110
1111 /**
1112 * Return Page/Group Avatar
1113 *
1114 * @since 2.0
1115 *
1116 * @return string
1117 */
1118 returnAccountAvatar : function(source){
1119 if (typeof source.local_avatar_url !== "undefined" && source.local_avatar_url !== '') {
1120 return source.local_avatar_url;
1121 }
1122 if (typeof source.avatar_url !== "undefined" && source.avatar_url !== '') {
1123 return source.avatar_url;
1124 }
1125
1126 return false;
1127 },
1128
1129 checkManualEmpty : function(){
1130 var self = this;
1131 return self.checkNotEmpty(self.appCredentials.access_token) && self.checkNotEmpty(self.appCredentials.access_token_secret);
1132 },
1133
1134 closeConnectAccountPopup : function(){
1135 var self = this;
1136 self.appCredentials = {
1137 app_name : '',
1138 consumer_key : '',
1139 consumer_secret : '',
1140 access_token : '',
1141 access_token_secret : ''
1142 };
1143 self.viewsActive.connectAccountPopup = false;
1144 },
1145
1146 checkNewAccount : function(){
1147 var self = this;
1148 if( self.newAccountData !== undefined ){
1149 if( self.newAccountData['error'] !== undefined ){
1150 self.accountDetails = self.newAccountData;
1151 }
1152 }
1153 },
1154 checkAccountDetails : function(){
1155 var self = this;
1156 return self.accountDetails !== undefined &&
1157 self?.accountDetails?.access_token !== undefined &&
1158 self?.accountDetails?.access_token_secret !== undefined &&
1159 self.checkNotEmpty(self?.accountDetails?.access_token) &&
1160 self.checkNotEmpty(self?.accountDetails?.access_token_secret);
1161
1162 },
1163
1164 checkAppData : function(){
1165 var self = this;
1166 return self?.accountDetails?.app_name !== undefined &&
1167 self?.accountDetails?.consumer_key !== undefined &&
1168 self?.accountDetails?.consumer_secret !== undefined &&
1169 self.checkNotEmpty(self?.accountDetails?.app_name) &&
1170 self.checkNotEmpty(self?.accountDetails?.consumer_key) &&
1171 self.checkNotEmpty(self?.accountDetails?.consumer_secret);
1172 },
1173
1174 deleteAccount : function(deleteApp = false){
1175 var self = this;
1176 self.loadingAjax = true;
1177 var deleteData = {
1178 action : 'ctf_feed_saver_manager_delete_account',
1179 'nonce' : self.nonce,
1180 deleteApp : deleteApp
1181 };
1182 self.ajaxPost(deleteData, function(_ref){
1183 var data = _ref.data;
1184 self.accountDetails = data;
1185 self.loadingAjax = false;
1186 });
1187 },
1188
1189 connectAccountLink : function(){
1190 window.location = this.appOAUTH;
1191 },
1192
1193 /**
1194 * Connect Twitter Account Manually
1195 *
1196 * @since 2.0
1197 */
1198 connectManualAccount : function(){
1199 var self = this;
1200 if( self.checkManualEmpty() ){
1201 self.loadingAjax = true;
1202 var connectManualAccountData = {
1203 action : 'ctf_feed_saver_manager_connect_manual_account',
1204 'nonce' : self.nonce,
1205 app_name : self.appCredentials.app_name,
1206 consumer_key : self.appCredentials.consumer_key,
1207 consumer_secret : self.appCredentials.consumer_secret,
1208 access_token : self.appCredentials.access_token,
1209 access_token_secret : self.appCredentials.access_token_secret
1210 };
1211 self.ajaxPost(connectManualAccountData, function(_ref){
1212 var data = _ref.data;
1213 if(data['error'] === undefined){
1214 self.accountDetails = data;
1215 self.manualAccountResp = 'success';
1216 setTimeout(function(){
1217 self.viewsActive['connectAccountPopup'] = false;
1218 self.manualAccountResp = false;
1219 }, 1000)
1220 }else{
1221 self.manualAccountResp = 'error';
1222 setTimeout(function(){
1223 self.manualAccountResp = false;
1224 }, 3000)
1225 }
1226 self.loadingAjax = false;
1227 });
1228 }
1229 },
1230
1231 }
1232 });
1233
1234