PluginProbe ʕ •ᴥ•ʔ
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress / trunk
Smash Balloon Social Post Feed – Simple Social Feeds for WordPress vtrunk
4.12.0 4.10.0 4.9.0 4.8.1 trunk 1.0 1.1 1.12.1 1.2.3 1.2.4 1.2.5 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.5 1.5.1 1.5.2 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.5.1 1.6.6 1.6.6.1 1.6.6.2 1.6.6.3 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.9.0 1.9.1 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.8.1 1.9.9 1.9.9.1 1.9.9.2 1.9.9.3 2.0 2.0.1 2.1 2.1.1 2.1.2 2.1.3 2.10 2.11 2.11.1 2.12 2.12.1 2.12.2 2.12.3 2.12.4 2.13 2.14 2.14.1 2.15 2.15.1 2.16 2.16.1 2.17 2.17.1 2.18 2.18.1 2.18.2 2.18.3 2.19 2.19.1 2.19.2 2.19.3 2.2 2.2.1 2.3 2.3.1 2.3.10 2.3.2 2.3.3 2.3.4 2.3.6 2.3.7 2.3.8 2.3.9 2.4 2.4.1 2.4.1.1 2.4.1.2 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5 2.5.1 2.5.2 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.7 2.7.1 2.7.2 2.8 2.9 2.9.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.7.5 4.7.6 4.7.7
custom-facebook-feed / admin / builder / assets / js / builder.js
custom-facebook-feed / admin / builder / assets / js Last commit date
add-source.js 2 years ago builder.js 1 week ago confirm-dialog.js 4 years ago date_i18n.js 5 years ago install-plugin-popup.js 4 years ago jquery.tooltipster.min.js 4 years ago oembed.js 5 years ago owl.autoheight.js 5 years ago popup-focus-trap.js 1 week ago ressources.js 4 years ago tooltip-wizard.js 4 years ago vue-color.min.js 5 years ago
builder.js
3517 lines
1 var cffBuilder,
2 cffStorage = window.localStorage,
3 sketch = VueColor.Sketch;
4
5 /**
6 * VueJS Dummy Lightbox
7 *
8 * @since 4.0
9 */
10 Vue.component('cff-dummy-lightbox', {
11 name: 'cff-dummy-lightbox',
12 template: '#cff-dummy-lightbox',
13 props: ['customizerScreens','customizerFeedData'],
14 methods : {
15
16 }
17 });
18
19 /**
20 * VueJS Iframe, Link, Video Component
21 *
22 * @since 4.0
23 */
24 Vue.component('cff-iframe-media-component', {
25 name: 'cff-iframe-media-component',
26 template: '#cff-iframe-media-component',
27 props: ['postmedia','customizerFeedData','singlePost','pluginType'],
28 methods : {
29 /**
30 * Check Whether to display the Iframe (video + sound)
31 * Depending on the feed settings
32 *
33 * @since 4.0
34 *
35 * @return bool
36 */
37 checkIframePostDisplay : function( postMedia ){
38 var self = this;
39 return postMedia.type == 'embed' &&
40 (
41 ( self.customizerFeedData.settings.include.includes('media') && postMedia.site == 'video' )
42 ||
43 ( self.customizerFeedData.settings.include.includes('sharedlinks') && postMedia.site != 'video' )
44 );
45 },
46 }
47 });
48 /**
49 * VueJS Iframe, Link, Video Component
50 *
51 * @since 4.0
52 */
53 Vue.component('cff-free-linkbox-component', {
54 name: 'cff-free-linkbox-component',
55 template: '#cff-free-linkbox-component',
56 props: ['postmedia','customizerFeedData','singlePost','pluginType'],
57 methods : {
58 /**
59 * Check Whether to display the Iframe (video + sound)
60 * Depending on the feed settings
61 *
62 * @since 4.0
63 *
64 * @return bool
65 */
66 checkIframePostDisplay : function( postMedia ){
67 var self = this;
68 return postMedia.type == 'embed' &&
69 (
70 ( self.customizerFeedData.settings.include.includes('media') && postMedia.site == 'video' )
71 ||
72 ( self.customizerFeedData.settings.include.includes('sharedlinks') && postMedia.site != 'video' )
73 );
74 },
75 }
76 });
77
78 /**
79 * VueJS Post Preview Components
80 *
81 * @since 4.0
82 */
83 var postPreviewComponents = [
84 'author',
85 'text',
86 'event-detail',
87 'media',
88 'meta',
89 'overlay',
90 'lightbox',
91 'full-layout',
92 'half-layout',
93 'thumb-layout',
94 'videosposts',
95 'reviewsposts',
96 'dummy-lightbox',
97 'free-icon',
98 'likebox'
99
100 ];
101
102 postPreviewComponents.forEach( function( component ) {
103 var nameComponent = 'cff-post-'+component+'-component';
104 Vue.component( nameComponent , {
105 template: '#' + nameComponent,
106 props: ['singlePost','customizerFeedData','translatedText','parent','lightBox','dummyLightBoxData','pluginType']
107 });
108 });
109
110
111
112 /**
113 * VueJS Global App Builder
114 *
115 * @since 4.0
116 */
117 cffBuilder = new Vue({
118 el: '#cff-builder-app',
119 http: {
120 emulateJSON: true,
121 emulateHTTP: true
122 },
123 components: {
124 'sketch-picker': sketch
125 },
126 mixins: [VueClickaway.mixin],
127 data: {
128 nonce : cff_builder.nonce,
129 admin_nonce: cff_builder.admin_nonce,
130 plugins: cff_builder.installPluginsPopup,
131 dismissLite : cff_builder.facebook_feed_dismiss_lite,
132 supportPageUrl: cff_builder.supportPageUrl,
133 builderUrl : cff_builder.builderUrl,
134 pluginType : cff_builder.pluginType,
135 genericText : cff_builder.genericText,
136 ajaxHandler : cff_builder.ajax_handler,
137 adminPostURL : cff_builder.adminPostURL,
138 widgetsPageURL : cff_builder.widgetsPageURL,
139 translatedText : cff_builder.translatedText,
140 socialShareLink : cff_builder.socialShareLink,
141 licenseType: cff_builder.licenseType,
142 freeCtaShowFeatures: false,
143 upgradeUrl: cff_builder.upgradeUrl,
144
145 welcomeScreen : cff_builder.welcomeScreen,
146 allFeedsScreen : cff_builder.allFeedsScreen,
147 extensionsPopup : cff_builder.extensionsPopup,
148 mainFooterScreen : cff_builder.mainFooterScreen,
149 embedPopupScreen : cff_builder.embedPopupScreen,
150
151 newManualSourcePopup : cff_builder.newManualSourcePopup,
152
153 selectSourceScreen : cff_builder.selectSourceScreen,
154 customizeScreensText : cff_builder.customizeScreens,
155 dialogBoxPopupScreen : cff_builder.dialogBoxPopupScreen,
156 selectFeedTypeScreen : cff_builder.selectFeedTypeScreen,
157 selectFeedTemplateScreen : cff_builder.selectFeedTemplateScreen,
158 addFeaturedPostScreen : cff_builder.addFeaturedPostScreen,
159 addFeaturedAlbumScreen : cff_builder.addFeaturedAlbumScreen,
160 addVideosPostScreen : cff_builder.addVideosPostScreen,
161 dummyLightBoxData : cff_builder.dummyLightBoxData,
162
163 svgIcons : cff_builder.svgIcons,
164 feedsList : cff_builder.feeds,
165 feedTypes : cff_builder.feedTypes,
166 socialInfo : cff_builder.socialInfo,
167 sourcesList : cff_builder.sources,
168 links : cff_builder.links,
169 legacyFeedsList : cff_builder.legacyFeeds,
170 activeExtensions : cff_builder.activeExtensions,
171 advancedFeedTypes : cff_builder.advancedFeedTypes,
172 groupSourcesNumber : cff_builder.groupSourcesNumber,
173 //Selected Feed type => TimeLine / Photos ... or Advanced ones!
174 selectedFeed : 'timeline',
175
176 // Will be changed depending on the feed type Selected ()
177 type : [
178 'links',
179 'events',
180 'videos',
181 'photos',
182 'albums',
183 'statuses'
184 ],
185
186 selectedSources : [],
187 viewsActive : {
188 //Screens where the footer widget is disabled
189 footerDiabledScreens : [
190 'welcome',
191 'selectFeed'
192 ],
193
194 // welcome, selectFeed
195 pageScreen : 'welcome',
196
197 // feedsType, selectSource, feedsTypeGetProcess
198 selectedFeedSection : 'feedsType',
199
200 sourcePopup : false,
201 feedtypesPopup : false,
202 feedtemplatesPopup : false,
203 // step_1 [Add New Source] , step_2 [Connect to a user pages/groups], step_3 [Add Manually]
204 sourcePopupScreen : 'redirect_1',
205
206 // creation or customizer
207 sourcePopupType : 'creation',
208 extensionsPopupElement : false,
209 feedTypeElement : null,
210 instanceFeedActive : null,
211 clipboardCopiedNotif : false,
212 legacyFeedsShown : false,
213 editName : false,
214 embedPopup : false,
215 embedPopupScreen : 'step_1',
216 embedPopupSelectedPage : null,
217
218 // onboarding
219 onboardingPopup : cff_builder.allFeedsScreen.onboarding.active,
220 onboardingStep : 1,
221
222 // customizer onboarding
223 onboardingCustomizerPopup : cff_builder.customizeScreens.onboarding.active,
224
225 // plugin install popup
226 installPluginPopup : false,
227 installPluginModal: 'instagram'
228 },
229
230 //Feeds Pagination
231 feedPagination : {
232 feedsCount : cff_builder.feedsCount != undefined ? cff_builder.feedsCount : null,
233 pagesNumber : 1,
234 currentPage : 1,
235 itemsPerPage : cff_builder.itemsPerPage != undefined ? cff_builder.itemsPerPage : null,
236 },
237
238 //Add New Source
239 newSourceData : cff_builder.newSourceData ? cff_builder.newSourceData : null,
240 sourceConnectionURLs : cff_builder.sourceConnectionURLs,
241 returnedApiSourcesList : [],
242 addNewSource : {
243 typeSelected : 'page',
244 manualSourceID : null,
245 manualSourceToken : null
246 },
247 selectedSourcesToConnect : [],
248
249 //Feeds Types Get Info
250 extraProcessFeedsTypes : [
251 //'events',
252 'singlealbum',
253 'featuredpost',
254 'videos'
255 ],
256 isCreateProcessGood : false,
257 feedCreationInfoUrl : null,
258 feedsSelected : [],
259 selectedBulkAction : false,
260 singleAlbumFeedInfo : {
261 url : '',
262 info : {},
263 success: false,
264 isError : false
265 },
266 featuredPostFeedInfo : {
267 url : '',
268 info : {},
269 success: false,
270 isError : false
271 },
272 videosTypeInfo : {
273 type : 'all',
274 info : {},
275 playListUrl : null,
276 success: false,
277 playListUrlError : false
278 },
279
280 customizerFeedDataInitial : null,
281 customizerFeedData : cff_builder.customizerFeedData,
282 wordpressPageLists : cff_builder.wordpressPageLists,
283 iscustomizerScreen : (cff_builder.customizerFeedData != undefined && cff_builder.customizerFeedData != false),
284
285 customizerSidebarBuilder : cff_builder.customizerSidebarBuilder,
286 feedTemplates : cff_builder.feedTemplates,
287 customizerScreens : {
288 activeTab : 'customize',
289 printedType : {},
290 activeSection : null,
291 printedTemplate : {},
292
293 previewScreen : 'desktop',
294 sourceExpanded : null,
295 sourcesChoosed : [],
296 inputNameWidth : '0px',
297 activeSectionData : null,
298 parentActiveSection : null, //For nested Setions
299 parentActiveSectionData : null, //For nested Setions
300 activeColorPicker : null,
301 popupBackButton : ['photos','videos','albums','events','reviews','featuredpost','singlealbum','socialwall', 'feedTemplates']
302 },
303 previewScreens: [
304 'desktop',
305 'tablet',
306 'mobile'
307 ],
308
309 nestedStylingSection : [
310 'post_styling_author',
311 'post_styling_text',
312 'post_styling_date',
313 'post_styling_media',
314 'post_styling_social',
315 'post_styling_eventtitle',
316 'post_styling_eventdetails',
317 'post_styling_link',
318 'post_styling_desc',
319 'post_styling_sharedlinks'
320 ],
321
322 sourceToDelete : {},
323 feedToDelete : {},
324 dialogBox : {
325 active : false,
326 type : null, //deleteSourceCustomizer
327 heading : null,
328 description : null
329 },
330
331 feedStyle : '',
332 expandedPostText : [],
333 showedSocialShareTooltip : null,
334 showedCommentSection : [],
335
336 //LightBox Object
337 lightBox : {
338 visibility : 'hidden',
339 type : null,
340 post : null,
341 activeImage : null,
342 albumIndex : 0,
343 videoSource : null
344 },
345 highLightedSection : 'all',
346
347 tooltip : {
348 text : '',
349 hover : false,
350 hoverType : 'outside'
351 },
352 //Loading Bar
353 fullScreenLoader : false,
354 appLoaded : false,
355 previewLoaded : false,
356 loadingBar : true,
357 notificationElement : {
358 type : 'success', // success, error, warning, message
359 text : '',
360 shown : null
361 },
362
363 //Onboarding Wizard
364 onboardingWizardContent : cff_builder.onboardingWizardContent,
365 currentOnboardingWizardStep : 0,
366 stepAnnouncement : '',
367 onboardingWizardStepContent : {},
368 currentOnboardingWizardActiveSettings : {},
369 onboardingSuccessMessages : cff_builder.onboardingWizardContent.successMessages,
370 onboardingSuccessMessagesDisplay : [],
371 onboardingWizardDone : 'false',
372 isSetupPage : cff_builder.isSetupPage,
373 setupLicencekey : '',
374 setupLicencekeyError : null,
375 licenseLoading : false
376 },
377 computed : {
378 feedStyleOutput : function(){
379 return this.customizerStyleMaker();
380 },
381 singleHolderData : function(){
382 return this.singleHolderParams();
383 }
384
385 },
386 created: function(){
387 var self = this;
388 if( self.customizerFeedData ){
389 setTimeout(function(){
390 self.generateMasonryGridHeight('update');
391 self.generateCarouselSettings();
392 }, 2000);
393 self.customizerFeedDataInitial = JSON.parse(JSON.stringify(self.customizerFeedData))
394 if(self.customizerFeedData.feed_info.id == 'legacy'){
395 self.customizerFeedData.settings.layout = 'full';
396 }
397 self.customizerScreens.printedTemplate = self.feedTemplates[0];
398 }
399
400 if(self.customizerFeedData == undefined){
401 if(self.sourcesList.length == 1){
402 self.selectedSources.push(self.sourcesList[0].account_id);
403 }
404 self.feedPagination.pagesNumber = self.feedPagination.feedsCount != null ? Math.ceil(self.feedPagination.feedsCount / self.feedPagination.itemsPerPage) : 1
405 }
406
407 if(self.newManualSourcePopup != undefined && self.newManualSourcePopup == true){
408 self.viewsActive.sourcePopupScreen = 'step_3';
409 self.activateView('sourcePopup', 'creation');
410 }
411
412 if(self?.onboardingWizardContent !== undefined){
413 self?.onboardingWizardContent.steps.forEach( step => {
414 self.onboardingWizardStepContent[step.id] = step;
415 } );
416 self.checkActiveOnboardingWizardSettings()
417 }
418
419 self.loadingBar = false;
420 /* Onboarding - move elements so the position is in context */
421 self.positionOnboarding();
422 setTimeout(function(){
423 self.positionOnboarding();
424 }, 500);
425
426 if(self?.onboardingWizardContent !== undefined){
427 self?.onboardingWizardContent.steps.forEach( step => {
428 self.onboardingWizardStepContent[step.id] = step;
429 } );
430 self.checkActiveOnboardingWizardSettings()
431 }
432
433 if( cffStorage?.isSetupPage !== 'true' && cffStorage?.isSetupPage !== true ){
434 self.appLoaded = true;
435 }
436
437 if(cffStorage?.setCurrentStep !== undefined){
438 self.currentOnboardingWizardStep = 1;
439 self.recordUsageEvent( 'setup_wizard_started' );
440 cffStorage.removeItem("setCurrentStep");
441 }
442
443 },
444 methods: {
445 updateColorValue : function(id){
446 var self = this;
447 self.customizerFeedData.settings[id] = (self.customizerFeedData.settings[id].a == 1) ? self.customizerFeedData.settings[id].hex : self.customizerFeedData.settings[id].hex8;
448 },
449 /**
450 * Show & Hide View
451 *
452 * @since 4.0
453 */
454 activateView : function(viewName, sourcePopupType = 'creation', ajaxAction = false){
455 var self = this;
456 if(viewName === 'feedtemplatesPopupCustomizer'){
457 self.activateView('feedtemplatesPopup');
458 self.activateView('extensionsPopupElement');
459 }else{
460 self.viewsActive[viewName] = (self.viewsActive[viewName] == false ) ? true : false;
461 if(viewName === 'sourcePopup'){
462 self.viewsActive.sourcePopupType = sourcePopupType;
463 if(self.customizerFeedData != undefined && sourcePopupType != 'updateCustomizer'){
464 Object.assign(self.customizerScreens.sourcesChoosed,self.customizerFeedData.settings.sources);
465 }
466 if(self.customizerFeedData != undefined && sourcePopupType == 'updateCustomizer'){
467 self.viewsActive.sourcePopupType = 'customizer';
468 //self.viewsActive.sourcePopup = true;
469 self.customizerFeedData.settings.sources = self.customizerScreens.sourcesChoosed;
470 }
471
472 if( ajaxAction !== false ){
473 self.customizerControlAjaxAction( ajaxAction );
474 }
475 }
476 if(viewName === 'feedtypesPopup'){
477 self.viewsActive.feedTypeElement = null;
478 if(self.viewsActive['feedtypesPopup'] == true){
479 self.viewsActive.extensionsPopupElement = null;
480 }
481 }
482 if(viewName === 'extensionsPopupElement' && self.customizerFeedData !== undefined){
483 //self.activateView('feedtypesPopup');
484 }
485 if(viewName == 'editName'){
486 document.getElementById("cff-csz-hd-input").focus();
487 }
488 if(viewName == 'embedPopup' && ajaxAction == true){
489 self.saveFeedSettings();
490 }
491 if((viewName == 'sourcePopup' || viewName == 'sourcePopupType') && sourcePopupType == 'creationRedirect'){
492 setTimeout(function(){
493 self.$refs.addSourceRef.processFBConnect()
494 },3500);
495 }
496 }
497
498
499 self.$forceUpdate();
500 self.movePopUp();
501 },
502
503 /**
504 * Show/Hide View or Redirect to plugin dashboard page
505 *
506 * @since 4.0
507 */
508 activateViewOrRedirect: function(viewName, pluginName, plugin) {
509 var self = this;
510
511 if ( plugin.installed && plugin.activated ) {
512 window.location = plugin.dashboard_permalink;
513 return;
514 }
515
516 self.viewsActive[viewName] = (self.viewsActive[viewName] == false ) ? true : false;
517
518 if(viewName == 'installPluginPopup'){
519 self.viewsActive.installPluginModal = pluginName;
520 }
521
522 self.movePopUp();
523 cffBuilder.$forceUpdate();
524 },
525
526 movePopUp : function(){
527 var overlay = document.querySelectorAll("sb-fs-boss");
528 if (overlay.length > 0) {
529 document.getElementById("wpbody-content").prepend(overlay[0]);
530 }
531 },
532
533 /**
534 * Check if View is Active
535 *
536 * @since 4.0
537 *
538 * @return boolean
539 */
540 checkActiveView : function(viewName){
541 return this.viewsActive[viewName];
542 },
543
544 /**
545 * Switch & Change Feed Screens
546 *
547 * @since 4.0
548 */
549 switchScreen: function(screenType, screenName){
550 let self = this;
551 this.viewsActive[screenType] = screenName;
552 cffBuilder.$forceUpdate();
553 // SMASH-1378 a11y (WCAG 2.4.3): step transitions swap the visible
554 // section via v-if, but focus stayed on the now-hidden Next button
555 // and fell through to the next focusable in the DOM (the floating
556 // Help Widget button). Move focus into the newly shown step's
557 // heading so keyboard/SR users keep their place in the flow. Mirrors
558 // the IG builder step-heading-focus pattern used elsewhere in 1378.
559 self.$nextTick(function () {
560 let createCtn = document.querySelector('.cff-fb-create-ctn');
561 if (!createCtn) return;
562 // The visible step is the section container that is NOT hidden
563 // by its v-if (Vue removes hidden v-if nodes from the DOM).
564 let heading = createCtn.querySelector(
565 '.cff-fb-types-ctn h4, .cff-fb-slctsrc-ctn h4, .cff-fb-sec-heading h4'
566 );
567 if (!heading) return;
568 if (!heading.hasAttribute('tabindex')) {
569 heading.setAttribute('tabindex', '-1');
570 }
571 heading.focus();
572 if (typeof heading.scrollIntoView === 'function') {
573 heading.scrollIntoView({ block: 'nearest' });
574 }
575 });
576 },
577
578 /**
579 * Check if Value is Empty
580 *
581 * @since 4.0
582 *
583 * @return boolean
584 */
585 checkNotEmpty : function(value){
586 return value != null && value.replace(/ /gi,'') != '';
587 },
588
589 /**
590 * Check if Value exists in Array Object
591 *
592 * @since 4.0
593 *
594 * @return boolean
595 */
596 checkObjectArrayElement : function(objectArray, object, byWhat){
597 var objectResult = objectArray.filter(function(elem){
598 return elem[byWhat] == object[byWhat];
599 });
600 return (objectResult.length > 0) ? true : false;
601 },
602
603 /**
604 * Check if Data Setting is Enabled
605 *
606 * @since 4.0
607 *
608 * @return boolean
609 */
610 valueIsEnabled : function(value){
611 return value == 1 || value == true || value == 'true' || value == 'on';
612 },
613
614
615 /**
616 * Parse JSON
617 *
618 * @since 4.0
619 *
620 * @return jsonObject / Boolean
621 */
622 jsonParse : function(jsonString){
623 try {
624 return JSON.parse(jsonString);
625 } catch(e) {
626 return false;
627 }
628 },
629
630
631 /**
632 * Ajax Post Action
633 *
634 * @since 4.0
635 */
636 ajaxPost : function(data, callback){
637 var self = this;
638 data['nonce'] = data.nonce ? data.nonce : this.nonce;
639 self.$http.post(self.ajaxHandler,data).then(callback);
640 },
641
642 /**
643 * Check if Object has Nested Property
644 *
645 * @since 4.0
646 *
647 * @return boolean
648 */
649 hasOwnNestedProperty : function(obj,propertyPath) {
650 if (!propertyPath){return false;}var properties = propertyPath.split('.');
651 for (var i = 0; i < properties.length; i++) {
652 var prop = properties[i];
653 if (!obj || !obj.hasOwnProperty(prop)) {
654 return false;
655 } else {
656 obj = obj[prop];
657 }
658 }
659 return true;
660 },
661
662
663 /**
664 * Feed List Pagination
665 *
666 * @since 4.0
667 */
668 feedListPagination : function(type){
669 var self = this,
670 currentPage = self.feedPagination.currentPage,
671 pagesNumber = self.feedPagination.pagesNumber;
672 self.loadingBar = true;
673 if((currentPage != 1 && type == 'prev') || (currentPage < pagesNumber && type == 'next')){
674 self.feedPagination.currentPage = (type == 'next') ?
675 (currentPage < pagesNumber ? (parseInt(currentPage) + 1) : pagesNumber) :
676 (currentPage > 1 ? (parseInt(currentPage) - 1) : 1);
677
678
679 var postData = {
680 action : 'cff_feed_saver_manager_get_feed_list_page',
681 page : self.feedPagination.currentPage
682 };
683 self.ajaxPost(postData, function(_ref){
684 var data = _ref.data;
685 if(data){
686 self.feedsList = data;
687 }
688 self.loadingBar = false;
689 });
690 cffBuilder.$forceUpdate();
691 }
692 },
693
694 /**
695 * Choose Feed Type
696 *
697 * @since 4.0
698 */
699 chooseFeedType : function(feedTypeGroup, feedElement, iscustomizerPopup = false){
700 var self = this;
701 if(feedTypeGroup == 'advanced' && feedElement.extensionActive !== true){
702 self.viewsActive.extensionsPopupElement = feedElement.type;
703 if(self.customizerFeedData !== undefined){
704 self.activateView('feedtypesPopup');
705 }
706 self.selectedFeed = 'timeline';
707 } else {
708 self.selectedFeed = feedElement.type;
709 }
710 if(iscustomizerPopup){
711 self.viewsActive.feedTypeElement = self.selectedFeed;
712 }else{
713 self.setType( self.selectedFeed );
714 }
715
716 if (self.selectedFeed === null) {
717 self.selectedFeed = 'timeline';
718 }
719 cffBuilder.$forceUpdate();
720 },
721
722 /**
723 * Set Feed Type
724 *
725 * @since 4.0
726 */
727 setType : function(feedType){
728 var typesArray = [], self = this;
729 switch (feedType) {
730 case 'photos':
731 typesArray = ['photos'];
732 break;
733 case 'videos':
734 typesArray = ['videos'];
735 break;
736 case 'events':
737 typesArray = ['events'];
738 break;
739 case 'albums':
740 typesArray = ['albums'];
741 break;
742 default:
743 typesArray = ['links','events','videos','photos','albums','statuses'];
744 break;
745 }
746 self.type = typesArray;
747 if(self.customizerFeedData !== undefined){
748 self.customizerFeedData.settings.type = typesArray;
749 self.customizerFeedData.settings.feedtype = (typesArray.length == 1) ? typesArray[0] : 'timeline';
750 self.processFeedTypesSources( typesArray );
751 }
752 },
753
754 /**
755 * Feed Types Sources
756 *
757 * @since 4.0
758 */
759 processFeedTypesSources : function( typesArray ){
760 var self = this;
761 if( self.customizerFeedData.settings.feedtype == 'timeline'){
762 if( typesArray.includes('photos') ){
763 self.customizerFeedData.settings.photosource = 'timeline';
764 }
765 if( typesArray.includes('videos') ){
766 self.customizerFeedData.settings.videosource = 'timeline';
767 }
768 if( typesArray.includes('albums') ){
769 self.customizerFeedData.settings.albumsource = 'timeline';
770 }
771 if( typesArray.includes('events') ){
772 self.customizerFeedData.settings.eventsource = 'timeline';
773 }
774 }
775
776 if( self.customizerFeedData.settings.feedtype == 'photos' ){
777 self.customizerFeedData.settings.photosource = 'photospage';
778 }
779 if( self.customizerFeedData.settings.feedtype == 'videos' ){
780 self.customizerFeedData.settings.videosource = 'videospage';
781 }
782 if( self.customizerFeedData.settings.feedtype == 'albums' ){
783 self.customizerFeedData.settings.albumsource = 'photospage';
784 }
785 if( self.customizerFeedData.settings.feedtype == 'events' ){
786 self.customizerFeedData.settings.eventsource = 'eventspage';
787 }
788 },
789
790 /*
791 Feed Creation Process
792 */
793 creationProcessCheckAction : function(){
794 var self = this, checkBtnNext = false;
795 switch (self.viewsActive.selectedFeedSection) {
796 case 'feedsType':
797 checkBtnNext = self.selectedFeed != null ? true : false;
798 window.cffSelectedFeed = self.selectedFeed;
799 break;
800 case 'selectSource':
801 checkBtnNext = self.selectedSources.length > 0 ? true : false;
802 break;
803 case 'feedsTypeGetProcess':
804 if(self.selectedFeed == 'singlealbum' && self.checkNotEmpty(self.singleAlbumFeedInfo.url)){
805 checkBtnNext = true;
806 if(self.singleAlbumFeedInfo.url === self.feedCreationInfoUrl && self.singleAlbumFeedInfo.isError)
807 checkBtnNext = false;
808 else
809 self.singleAlbumFeedInfo.isError = false;
810
811 }
812 if(self.selectedFeed == 'featuredpost' && self.checkNotEmpty(self.featuredPostFeedInfo.url)){
813 checkBtnNext = true;
814 if(self.featuredPostFeedInfo.url === self.feedCreationInfoUrl && self.featuredPostFeedInfo.isError)
815 checkBtnNext = false;
816 else
817 self.featuredPostFeedInfo.isError = false;
818 }
819
820 if(self.selectedFeed == 'videos' && ( self.videosTypeInfo.type == 'all' || ( self.videosTypeInfo.type == 'playlist' && self.checkNotEmpty(self.videosTypeInfo.playListUrl) ) ) ) {
821 checkBtnNext = true;
822 if(self.videosTypeInfo.playListUrl === self.feedCreationInfoUrl && self.videosTypeInfo.playListUrlError)
823 checkBtnNext = false;
824 else
825 self.videosTypeInfo.playListUrlError = false;
826 }
827 break;
828 }
829 return checkBtnNext;
830 },
831 //Next Click in the Creation Process
832 creationProcessNext : function(){
833 var self = this;
834 switch (self.viewsActive.selectedFeedSection) {
835 case 'feedsType':
836 if(self.selectedFeed !== null){
837 if (self.selectedFeed === 'socialwall') {
838 window.location.href = cff_builder.pluginsInfo.social_wall.settingsPage;
839 return;
840 }
841 self.switchScreen('selectedFeedSection', 'selectSource');
842 }
843 break;
844 case 'selectSource':
845 if(self.selectedSources.length == 0){
846 self.processNotification("selectSourceError");
847 }
848 if(self.selectedSources.length > 0){
849 self.switchScreen('selectedFeedSection', 'feedsTypeGetProcess');
850 if(!self.extraProcessFeedsTypes.includes(self.selectedFeed))
851 self.isCreateProcessGood = true;
852 }
853 break;
854 case 'feedsTypeGetProcess':
855 //Getting Single Album Info
856 if(self.selectedFeed == 'singlealbum' && self.checkNotEmpty(self.singleAlbumFeedInfo.url)){
857 self.feedCreationInfoUrl = self.singleAlbumFeedInfo.url;
858 self.getSingleAlbumCreationProcessInfo();
859 }
860 //Getting Featured Post info
861 if(self.selectedFeed == 'featuredpost' && self.checkNotEmpty(self.featuredPostFeedInfo.url)){
862 self.feedCreationInfoUrl = self.featuredPostFeedInfo.url;
863 self.getFeaturedPostCreationProcessInfo();
864 }
865 //Getting PlayList Info
866 if(self.selectedFeed == 'videos' && ( self.videosTypeInfo.type == 'all' || ( self.videosTypeInfo.type == 'playlist' && self.checkNotEmpty(self.videosTypeInfo.playListUrl) ) ) ){
867 self.feedCreationInfoUrl = self.videosTypeInfo.playListUrl;
868 if(self.videosTypeInfo.type == 'all'){
869 self.submitNewFeed();
870 }else{
871 self.getVideosPlaylistCreationProcessInfo();
872 }
873 }
874 break;
875 }
876 if(self.isCreateProcessGood)
877 self.submitNewFeed();
878
879 cffBuilder.$forceUpdate();
880 },
881 changeVideoSource : function( videoSource ){
882 this.videosTypeInfo.type = videoSource;
883 cffBuilder.$forceUpdate();
884 },
885
886 //Next Click in the Onboarding Process
887 onboardingNext : function(){
888 this.viewsActive.onboardingStep ++;
889 this.onboardingHideShow();
890 cffBuilder.$forceUpdate();
891 },
892 //Previous Click in the Onboarding Process
893 onboardingPrev : function(){
894 this.viewsActive.onboardingStep --;
895 this.onboardingHideShow();
896 cffBuilder.$forceUpdate();
897 },
898 onboardingHideShow : function() {
899 var tooltips = document.querySelectorAll(".sb-onboarding-tooltip");
900 for (var i = 0; i < tooltips.length; i++){
901 tooltips[i].style.display = "none";
902 }
903 document.querySelectorAll(".sb-onboarding-tooltip-"+this.viewsActive.onboardingStep)[0].style.display = "block";
904
905 if (this.viewsActive.onboardingCustomizerPopup) {
906 if (this.viewsActive.onboardingStep === 2) {
907 this.switchCustomizerTab('customize');
908 } else if (this.viewsActive.onboardingStep === 3) {
909 this.switchCustomizerTab('settings');
910 }
911 }
912
913 },
914 //Close Click in the Onboarding Process
915 onboardingClose : function(){
916 var self = this,
917 wasActive = self.viewsActive.onboardingPopup ? 'newuser' : 'customizer';
918
919 document.getElementById("cff-builder-app").classList.remove('sb-onboarding-active');
920
921 self.viewsActive.onboardingPopup = false;
922 self.viewsActive.onboardingCustomizerPopup = false;
923
924 this.switchCustomizerTab('customize');
925 self.viewsActive.onboardingStep = 0;
926 var postData = {
927 action : 'cff_dismiss_onboarding',
928 was_active : wasActive,
929 };
930 self.ajaxPost(postData, function(_ref){
931 var data = _ref.data;
932 });
933 cffBuilder.$forceUpdate();
934 },
935 positionOnboarding : function(){
936 var self = this,
937 onboardingElem = document.querySelectorAll(".sb-onboarding-overlay")[0],
938 wrapElem = document.getElementById("cff-builder-app");
939
940 if (onboardingElem === null || typeof onboardingElem === 'undefined') {
941 return;
942 }
943
944 if (self.viewsActive.onboardingCustomizerPopup && self.iscustomizerScreen) {
945 if (document.getElementById("sb-onboarding-tooltip-customizer-1") !== null) {
946 wrapElem.classList.add('sb-onboarding-active');
947
948 var step1El = document.querySelectorAll(".cff-csz-header")[0];
949 step1El.appendChild(document.getElementById("sb-onboarding-tooltip-customizer-1"));
950
951 var step2El = document.querySelectorAll(".sb-customizer-sidebar-sec1")[0];
952 step2El.appendChild(document.getElementById("sb-onboarding-tooltip-customizer-2"));
953
954 var step3El = document.querySelectorAll(".sb-customizer-sidebar-sec1")[0];
955 step3El.appendChild(document.getElementById("sb-onboarding-tooltip-customizer-3"));
956
957 self.onboardingHideShow();
958 }
959 } else if (self.viewsActive.onboardingPopup && !self.iscustomizerScreen) {
960 if (cff_builder.allFeedsScreen.onboarding.type === 'single') {
961 if (document.getElementById("sb-onboarding-tooltip-single-1") !== null) {
962 wrapElem.classList.add('sb-onboarding-active');
963
964 var step1El = document.querySelectorAll(".cff-fb-wlcm-header .sb-positioning-wrap")[0];
965 step1El.appendChild(document.getElementById("sb-onboarding-tooltip-single-1"));
966
967 var step2El = document.querySelectorAll(".cff-table-wrap")[0];
968 if(step2El != undefined){
969 step2El.appendChild(document.getElementById("sb-onboarding-tooltip-single-2"));
970 }
971 self.onboardingHideShow();
972 }
973 } else {
974 if (document.getElementById("sb-onboarding-tooltip-multiple-1") !== null) {
975 wrapElem.classList.add('sb-onboarding-active');
976
977 var step1El = document.querySelectorAll(".cff-fb-wlcm-header .sb-positioning-wrap")[0];
978 step1El.appendChild(document.getElementById("sb-onboarding-tooltip-multiple-1"));
979
980 var step2El = document.querySelectorAll(".cff-fb-lgc-ctn")[0];
981 step2El.appendChild(document.getElementById("sb-onboarding-tooltip-multiple-2"));
982
983 var step3El = document.querySelectorAll(".cff-legacy-table-wrap")[0];
984 step3El.appendChild(document.getElementById("sb-onboarding-tooltip-multiple-3"));
985
986 self.activateView('legacyFeedsShown');
987 self.onboardingHideShow();
988 }
989 }
990
991 }
992 },
993 //Back Click in the Creation Process
994 creationProcessBack : function(){
995 var self = this;
996 switch (self.viewsActive.selectedFeedSection) {
997 case 'feedsType':
998 self.switchScreen('pageScreen', 'welcome');
999 break;
1000 case 'selectSource':
1001 self.switchScreen('selectedFeedSection', 'feedsType');
1002 break;
1003 case 'feedsTypeGetProcess':
1004 self.switchScreen('selectedFeedSection', 'selectSource');
1005 break;
1006 }
1007 cffBuilder.$forceUpdate();
1008 },
1009 checkCreationFeedTypeChosen : function(feedTypeChosen){
1010 var self = this, isShown = false;
1011 switch (feedTypeChosen) {
1012 case "singlealbum":
1013 isShown = self.activeExtensions.album && (self.viewsActive.selectedFeedSection == 'feedsTypeGetProcess' && self.selectedFeed == 'singlealbum');
1014 break;
1015 case "featuredpost":
1016 isShown = self.activeExtensions.featured_post && (self.viewsActive.selectedFeedSection == 'feedsTypeGetProcess' && self.selectedFeed == 'featuredpost');
1017 break;
1018 case "videos":
1019 isShown = (self.viewsActive.selectedFeedSection == 'feedsTypeGetProcess' && self.selectedFeed == 'videos');
1020 break;
1021 }
1022 return isShown;
1023 },
1024 //Get Single Album info in the creation Process
1025 getSingleAlbumCreationProcessInfo : function(){
1026 var self = this;
1027 var singleAlbumData = {
1028 action : 'cff_source_get_featured_post_preview',
1029 url_or_id : self.singleAlbumFeedInfo.url,
1030 source_id : self.selectedSources[0]
1031 };
1032 self.ajaxPost(singleAlbumData, function(_ref){
1033 var data = _ref.data;
1034 if(self.hasOwnNestedProperty(data,'error')){
1035 self.singleAlbumFeedInfo.isError = true, self.singleAlbumFeedInfo.success = false, self.singleAlbumFeedInfo.info = {};
1036 }else {
1037 self.singleAlbumFeedInfo.isError = false,self.singleAlbumFeedInfo.success = true;
1038 var albumID = data.id.split("_");
1039 albumID = albumID[1] != undefined ? albumID[1] : data.id;
1040
1041 self.singleAlbumFeedInfo.info = {
1042 title : data.attachments.data[0].title ? data.attachments.data[0].title : '',
1043 description : data.story ? data.story : '',
1044 thumbnail : self.hasOwnNestedProperty(data,'full_picture') ? data.full_picture : '',
1045 album : albumID
1046 };
1047 self.isCreateProcessGood = true;
1048 }
1049 });
1050 },
1051
1052 //Get Videos Play List Info
1053 getVideosPlaylistCreationProcessInfo : function(){
1054 var self = this,
1055 videosPlaylistData = {
1056 action : 'cff_source_get_playlist_post_preview',
1057 url_or_id : self.videosTypeInfo.playListUrl,
1058 source_id : self.selectedSources[0]
1059 };
1060 self.ajaxPost(videosPlaylistData, function(_ref){
1061 var data = _ref.data;
1062 if(self.hasOwnNestedProperty(data,'error')){
1063 self.videosTypeInfo.playListUrlError = true, self.videosTypeInfo.success = false;
1064 }else {
1065 self.videosTypeInfo.info = {
1066 playlistID : data.playlistID
1067 }
1068 self.videosTypeInfo.playListUrlError = false, self.videosTypeInfo.success = true;
1069 self.isCreateProcessGood = true;
1070 self.submitNewFeed();
1071 }
1072 });
1073
1074 },
1075
1076 //Get Featured Post info in the creation Process
1077 getFeaturedPostCreationProcessInfo : function(){
1078 var self = this;
1079 var featuredPostData = {
1080 action : 'cff_source_get_featured_post_preview',
1081 url_or_id : self.featuredPostFeedInfo.url,
1082 source_id : self.selectedSources[0]
1083 };
1084 self.ajaxPost(featuredPostData, function(_ref){
1085 var data = _ref.data;
1086 if(self.hasOwnNestedProperty(data,'error')){
1087 self.featuredPostFeedInfo.isError = true, self.featuredPostFeedInfo.success = false, self.featuredPostFeedInfo.info = {};
1088 }else {
1089 self.featuredPostFeedInfo.isError = false,self.featuredPostFeedInfo.success = true;
1090 self.featuredPostFeedInfo.info = {
1091 description : data.message ? data.message.substr(0, 60) + '...' : '',
1092 thumbnail : self.hasOwnNestedProperty(data,'full_picture') ? data.full_picture : '',
1093 featuredpost : data.id
1094 };
1095 self.isCreateProcessGood = true;
1096 }
1097 });
1098 },
1099 getSelectedSourceName : function(sourceID){
1100 var self = this;
1101 var sourceInfo = self.sourcesList.filter(function(source){
1102 return source.account_id == sourceID;
1103 });
1104 return (sourceInfo.length > 0) ? sourceInfo[0].username : '';
1105 },
1106 //Create & Submit New Feed
1107 submitNewFeed : function(){
1108 var self = this,
1109 newFeedData = {
1110 action : 'cff_feed_saver_manager_builder_update',
1111 sources : self.selectedSources,
1112 new_insert : 'true',
1113 sourcename : self.getSelectedSourceName(self.selectedSources[0]),
1114 feedtype : self.selectedFeed,
1115 type : self.type
1116 };
1117 if(self.selectedFeed == 'featuredpost'){
1118 newFeedData.featuredpost = self.featuredPostFeedInfo.info.featuredpost;
1119 }
1120 if(self.selectedFeed == 'singlealbum'){
1121 newFeedData.album = self.singleAlbumFeedInfo.info.album;
1122 }
1123 if(self.selectedFeed == 'videos'){
1124 newFeedData.playlist = (self.videosTypeInfo.info.playlistID != undefined && self.videosTypeInfo.type == 'playlist') ? self.videosTypeInfo.info.playlistID : '';
1125 }
1126 self.fullScreenLoader = true;
1127 self.ajaxPost(newFeedData, function(_ref){
1128 var data = _ref.data;
1129 if(data.feed_id && data.success){
1130 window.location = self.builderUrl + '&feed_id=' + data.feed_id;
1131 }
1132 });
1133 },
1134
1135 //Select & Choose the Feed Source
1136 checkSourceForEvents : function(source){
1137 return this.selectedFeed == 'events' && source.account_type == 'page' && source.privilege != 'events';
1138 },
1139 checkTypeForGroup : function(source){
1140 return source.account_type === 'group' && this.selectedFeed === 'photos';
1141 },
1142 selectSource : function(source){
1143 var self = this;
1144 isMultifeed = (self.activeExtensions['multifeed'] !== undefined && self.activeExtensions['multifeed'] == true);
1145 if(!self.checkSourceForEvents(source) && !self.checkTypeForGroup(source)){
1146 if(isMultifeed){
1147 if(self.selectedSources.includes(source.account_id)){
1148 self.selectedSources.splice(self.selectedSources.indexOf(source.account_id), 1);
1149 }else{
1150 self.selectedSources.push(source.account_id);
1151 }
1152 }else{
1153 self.selectedSources = (self.selectedSources.includes(source.account_id)) ? [] : [source.account_id];
1154 }
1155 }
1156 },
1157 processDomList : function(selector, attributes){
1158 document.querySelectorAll(selector).forEach( function(element) {
1159 attributes.map( function(attrName) {
1160 element.setAttribute(attrName[0], attrName[1]);
1161 });
1162 });
1163 },
1164 openTooltipBig : function(){
1165 var self = this, elem = window.event.currentTarget;
1166 self.processDomList('.cff-fb-onbrd-tltp-elem', [['data-active', 'false']]);
1167 elem.querySelector('.cff-fb-onbrd-tltp-elem').setAttribute('data-active', 'true');
1168 cffBuilder.$forceUpdate();
1169 },
1170 closeTooltipBig : function(){
1171 var self = this;
1172 self.processDomList('.cff-fb-onbrd-tltp-elem', [['data-active', 'false']]);
1173 cffBuilder.$forceUpdate();
1174 },
1175
1176 /*
1177 FEEDS List Actions
1178 */
1179
1180 /**
1181 * Switch Bulk Action
1182 *
1183 * @since 4.0
1184 */
1185 bulkActionClick : function(){
1186 var self = this;
1187 switch (self.selectedBulkAction) {
1188 case 'delete':
1189 if(self.feedsSelected.length > 0){
1190 self.openDialogBox('deleteMultipleFeeds')
1191 }
1192 break;
1193 }
1194 cffBuilder.$forceUpdate();
1195 },
1196
1197 /**
1198 * Duplicate Feed
1199 *
1200 * @since 4.0
1201 */
1202 feedActionDuplicate : function(feed){
1203 var self = this,
1204 feedsDuplicateData = {
1205 action : 'cff_feed_saver_manager_duplicate_feed',
1206 feed_id : feed.id
1207 };
1208 self.ajaxPost(feedsDuplicateData, function(_ref){
1209 var data = _ref.data;
1210 self.feedsList = Object.values(Object.assign({}, data));
1211 //self.feedsList = data;
1212 });
1213 cffBuilder.$forceUpdate();
1214 },
1215
1216 /**
1217 * Delete Feed
1218 *
1219 * @since 4.0
1220 */
1221 feedActionDelete : function(feeds_ids){
1222 var self = this,
1223 feedsDeleteData = {
1224 action : 'cff_feed_saver_manager_delete_feeds',
1225 feeds_ids : feeds_ids
1226 };
1227 self.ajaxPost(feedsDeleteData, function(_ref){
1228 var data = _ref.data;
1229 self.feedsList = Object.values(Object.assign({}, data));
1230 self.feedsSelected = [];
1231 });
1232 },
1233
1234 /**
1235 * View Feed Instances
1236 *
1237 * @since 4.0
1238 */
1239 viewFeedInstances : function(feed){
1240 var self = this;
1241 self.viewsActive.instanceFeedActive = feed;
1242 self.movePopUp();
1243 cffBuilder.$forceUpdate();
1244 },
1245
1246 /**
1247 * Select All Feeds in List
1248 *
1249 * @since 4.0
1250 */
1251 selectAllFeedCheckBox : function(){
1252 var self = this;
1253 if( !self.checkAllFeedsActive() ){
1254 self.feedsSelected = [];
1255 self.feedsList.forEach( function(feed) {
1256 self.feedsSelected.push(feed.id);
1257 });
1258 }else{
1259 self.feedsSelected = [];
1260 }
1261
1262 },
1263
1264 /**
1265 * Select Single Feed in List
1266 *
1267 * @since 4.0
1268 */
1269 selectFeedCheckBox : function(feedID){
1270 if(this.feedsSelected.includes(feedID)){
1271 this.feedsSelected.splice(this.feedsSelected.indexOf(feedID),1);
1272 }else{
1273 this.feedsSelected.push(feedID);
1274 }
1275 cffBuilder.$forceUpdate();
1276 },
1277
1278 /**
1279 * Check if All Feeds are Selected
1280 *
1281 * @since 4.0
1282 */
1283 checkAllFeedsActive : function(){
1284 var self = this,
1285 result = true;
1286 self.feedsList.forEach( function(feed) {
1287 if(!self.feedsSelected.includes(feed.id)){
1288 result = false;
1289 }
1290 });
1291
1292 return result;
1293 },
1294
1295
1296 /**
1297 * Copy text to clipboard
1298 *
1299 * @since 4.0
1300 */
1301 copyToClipBoard : function(value){
1302 var self = this;
1303 const el = document.createElement('textarea');
1304 el.className = 'cff-fb-cp-clpboard';
1305 el.value = value;
1306 document.body.appendChild(el);
1307 el.select();
1308 document.execCommand('copy');
1309 document.body.removeChild(el);
1310 self.notificationElement = {
1311 type : 'success',
1312 text : this.genericText.copiedClipboard,
1313 shown : "shown"
1314 };
1315 setTimeout(function(){
1316 self.notificationElement.shown = "hidden";
1317 }, 3000);
1318 cffBuilder.$forceUpdate();
1319 },
1320
1321
1322 /**
1323 * Check Post Show
1324 *
1325 * @since 4.0
1326 */
1327 shouldShowPostList : function(layout, singlePost){
1328 var self = this;
1329 return self.customizerFeedData.settings.layout == layout &&
1330 (
1331 (
1332 self.customizerFeedData.settings.feedtype == 'reviews' &&
1333 ((self.valueIsEnabled(self.customizerFeedData.settings.hidenegative) && singlePost.recommendation_type == 'positive') || !self.valueIsEnabled(self.customizerFeedData.settings.hidenegative) )
1334 )
1335 || self.customizerFeedData.settings.feedtype != 'reviews'
1336 )
1337 },
1338
1339
1340
1341 /*-------------------------------------------
1342 CUSTOMIZER FUNCTIONS
1343 -------------------------------------------*/
1344 /**
1345 * HighLight Section
1346 *
1347 * @since 4.0
1348 */
1349 isSectionHighLighted : function(sectionName){
1350 var self = this;
1351 return (self.highLightedSection === sectionName || self.highLightedSection === 'all')
1352 },
1353
1354 /**
1355 * Enable HightLight Section
1356 *
1357 * @since 4.0
1358 */
1359 enableHighLightSection : function(sectionId){
1360 var self = this,
1361 listPostSection = ['customize_feedlayout', 'customize_colorscheme', 'customize_posts','post_style','individual_elements'],
1362 headerSection = ['customize_header'],
1363 likeBoxSection = ['customize_likebox'],
1364 loadeMoreSection = ['customize_loadmorebutton'],
1365 lightBoxSection = ['customize_lightbox'],
1366 domBody = document.getElementsByTagName("body")[0];
1367
1368 self.dummyLightBoxData.visibility = 'hidden';
1369 domBody.classList.remove("no-overflow");
1370
1371 if( listPostSection.includes(sectionId) ){
1372 self.highLightedSection = 'postList';
1373 self.scrollToHighLightedSection("cff-post-list-section");
1374 }else if( headerSection.includes(sectionId) ){
1375 self.highLightedSection = 'header';
1376 self.scrollToHighLightedSection("cff-header-section");
1377 }else if( likeBoxSection.includes(sectionId) ){
1378 self.highLightedSection = 'likeBox';
1379 self.scrollToHighLightedSection("cff-like-box-section");
1380 }else if( loadeMoreSection.includes(sectionId) ){
1381 self.highLightedSection = 'loadMore';
1382 self.scrollToHighLightedSection("cff-load-more-section");
1383 }else if( lightBoxSection.includes(sectionId) ){
1384 self.highLightedSection = 'lightBox';
1385 self.dummyLightBoxData.visibility = 'shown';
1386 document.body.scrollTop = 0;
1387 document.documentElement.scrollTop = 0;
1388 domBody.classList.add("no-overflow");
1389 }else{
1390 self.highLightedSection = 'all';
1391 self.dummyLightBoxData.visibility = 'hidden';
1392 domBody.classList.remove("no-overflow");
1393 }
1394 },
1395
1396
1397 /**
1398 * Scroll to Highlighted Section
1399 *
1400 * @since 4.0
1401 */
1402 scrollToHighLightedSection : function(sectionId){
1403 const element = document.getElementById(sectionId);
1404 if(element != undefined && element != null){
1405 const y = element.getBoundingClientRect().top - 100 + window.pageYOffset - 10;
1406 window.scrollTo({top: y, behavior: 'smooth'});
1407 }
1408 },
1409
1410 /**
1411 * Enable & Show Color Picker
1412 *
1413 * @since 4.0
1414 */
1415 showColorPickerPospup : function(controlId){
1416 let self = this;
1417 self.customizerScreens.activeColorPicker = controlId;
1418 // SMASH-1378 a11y: move focus into the picker dialog when it
1419 // opens so keyboard users can immediately interact with it.
1420 self.$nextTick(function () {
1421 let popup = document.getElementById('sb-colorpicker-popup-' + controlId);
1422 if (!popup) return;
1423 // Prefer the first focusable input inside the sketch-picker
1424 // (hex/RGB/A inputs). Fall back to the picker dialog itself.
1425 let focusable = popup.querySelector('input, [tabindex]:not([tabindex="-1"]), button');
1426 if (focusable && focusable !== popup) {
1427 focusable.focus();
1428 } else {
1429 popup.focus();
1430 }
1431 });
1432 },
1433
1434 /**
1435 * Hide Color Picker
1436 *
1437 * When a controlId is passed (keyboard dismissal via Esc), focus is
1438 * returned to the swatch button so tab order stays predictable. The
1439 * mouse-driven clickaway path calls this without an argument, which
1440 * skips the refocus so we don't steal focus from wherever the user
1441 * just clicked.
1442 *
1443 * @since 4.0
1444 */
1445 hideColorPickerPospup : function(controlId){
1446 let self = this;
1447 self.customizerScreens.activeColorPicker = null;
1448 if (typeof controlId === 'string' && controlId) {
1449 // SMASH-1378 a11y: explicit keyboard dismissal — return
1450 // focus to the originating swatch button.
1451 self.$nextTick(function () {
1452 let swatch = document.getElementById('sb-colorpicker-swatch-' + controlId);
1453 if (swatch) swatch.focus();
1454 });
1455 }
1456 },
1457
1458 /**
1459 * Toggle Color Picker (open if closed, close if open)
1460 *
1461 * @since SMASH-1378
1462 */
1463 toggleColorPickerPospup : function(controlId){
1464 if (this.customizerScreens.activeColorPicker === controlId) {
1465 this.hideColorPickerPospup(controlId);
1466 } else {
1467 this.showColorPickerPospup(controlId);
1468 }
1469 },
1470
1471 switchCustomizerPreviewDevice : function(previewScreen){
1472 var self = this;
1473 self.customizerScreens.previewScreen = previewScreen;
1474 self.loadingBar = true;
1475 self.reinitCarouselHTML();
1476 setTimeout(function(){
1477 self.generateMasonryGridHeight('update');
1478 self.loadingBar = false;
1479 },200)
1480 cffBuilder.$forceUpdate();
1481 },
1482 /**
1483 * Roving-tabindex arrow-key navigation for the customizer sidebar
1484 * tablist (Customize / Settings). Ported from instagram-feed-pro.
1485 *
1486 * @since 4.0
1487 */
1488 handleCustomizerTabKeydown: function (event, direction) {
1489 let self = this,
1490 tabIds = Object.keys(self.customizerSidebarBuilder || {}),
1491 currentIdx = tabIds.indexOf(self.customizerScreens.activeTab),
1492 nextIdx = currentIdx;
1493 if (tabIds.length === 0 || currentIdx === -1) return;
1494 if (direction === 'right') {
1495 nextIdx = (currentIdx + 1) % tabIds.length;
1496 } else if (direction === 'left') {
1497 nextIdx = (currentIdx - 1 + tabIds.length) % tabIds.length;
1498 } else if (direction === 'home') {
1499 nextIdx = 0;
1500 } else if (direction === 'end') {
1501 nextIdx = tabIds.length - 1;
1502 }
1503 if (nextIdx === currentIdx) return;
1504 self.switchCustomizerTab(tabIds[nextIdx]);
1505 self.$nextTick(function () {
1506 let nextBtn = document.getElementById('sb-customizer-tab-' + tabIds[nextIdx]);
1507 if (nextBtn) nextBtn.focus();
1508 });
1509 },
1510
1511 switchCustomizerTab : function(tabId){
1512 var self = this,
1513 domBody = document.getElementsByTagName("body")[0];
1514 self.customizerScreens.activeTab = tabId;
1515 self.customizerScreens.activeSection = null;
1516 self.customizerScreens.activeSectionData = null;
1517 self.highLightedSection = 'all';
1518
1519 self.dummyLightBoxData.visibility = 'hidden';
1520 domBody.classList.remove("no-overflow");
1521 cffBuilder.$forceUpdate();
1522 },
1523 switchCustomizerSection : function(sectionId, section, isNested = false, isBackElements){
1524 var self = this;
1525 self.customizerScreens.parentActiveSection = null;
1526 self.customizerScreens.parentActiveSectionData = null;
1527 if(isNested){
1528 self.customizerScreens.parentActiveSection = self.customizerScreens.activeSection;
1529 self.customizerScreens.parentActiveSectionData = self.customizerScreens.activeSectionData;
1530 }
1531 self.customizerScreens.activeSection = sectionId;
1532 self.customizerScreens.activeSectionData = section;
1533 self.enableHighLightSection(sectionId);
1534 cffBuilder.$forceUpdate();
1535 },
1536 switchNestedSection : function(sectionId, section){
1537 var self = this;
1538 if(section !== null){
1539 self.customizerScreens.activeSection = sectionId;
1540 self.customizerScreens.activeSectionData = section;
1541 }else{
1542 var sectionArray = sectionId['sections'];
1543 var elementSectionData = self.customizerSidebarBuilder;
1544
1545 sectionArray.map(function(elm, index){
1546 elementSectionData = (elementSectionData[elm] != undefined && elementSectionData[elm] != null) ? elementSectionData[elm] : null;
1547 });
1548 if(elementSectionData != null){
1549 self.customizerScreens.activeSection = sectionId['id'];
1550 self.customizerScreens.activeSectionData = elementSectionData;
1551 }
1552 }
1553 cffBuilder.$forceUpdate();
1554 },
1555 backToPostElements : function(){
1556 var self = this,
1557 individual_elements = self.customizerSidebarBuilder['customize'].sections.customize_posts.nested_sections.individual_elements;
1558 self.customizerScreens.activeSection = 'customize_posts';
1559 self.customizerScreens.activeSectionData= self.customizerSidebarBuilder['customize'].sections.customize_posts;
1560 self.switchCustomizerSection('individual_elements', individual_elements, true, true);
1561 cffBuilder.$forceUpdate();
1562 },
1563
1564 processDateRange : function(){
1565 var self = this,
1566 settings = self.customizerFeedData.settings;
1567 if(settings['daterangefromtype'] == 'relative'){
1568 self.customizerFeedData.settings['from'] = settings['daterangefromrelative'];
1569 }else{
1570 self.customizerFeedData.settings['from'] = settings['daterangefromspecific'];
1571 }
1572
1573 if(settings['daterangeuntiltype'] == 'relative'){
1574 self.customizerFeedData.settings['until'] = settings['daterangeuntilrelative'];
1575 }else{
1576 self.customizerFeedData.settings['until'] = settings['daterangeuntilspecific'];
1577 }
1578
1579 self.customizerControlAjaxAction('feedFlyPreview');
1580 },
1581
1582 /**
1583 * Roving tabindex + arrow-key navigation for radiogroup-pattern
1584 * controls (toggleset, togglebutton). Walks the rendered DOM so
1585 * we honor v-show / aria-disabled visibility, moves focus to the
1586 * target option, and auto-activates per the WAI-ARIA radio pattern.
1587 *
1588 * @param {KeyboardEvent} event Keyboard event from the current radio.
1589 * @param {Object} control Control definition (id, options, ajaxAction).
1590 * @param {String} action 'prev' | 'next' | 'first' | 'last'.
1591 * @since 4.0
1592 */
1593 onTogglesetArrowKey: function (event, control, action) {
1594 let self = this;
1595 let currentEl = event.currentTarget;
1596 if (!currentEl) {
1597 return;
1598 }
1599 let group = currentEl.closest('[role="radiogroup"]');
1600 if (!group) {
1601 return;
1602 }
1603 // Only options that are currently rendered (v-show keeps the
1604 // node but sets display:none) and not aria-disabled.
1605 let radios = Array.prototype.filter.call(
1606 group.querySelectorAll('[role="radio"]'),
1607 function (el) {
1608 if (el.getAttribute('aria-disabled') === 'true') {
1609 return false;
1610 }
1611 // v-show toggles inline `display: none`.
1612 return el.style.display !== 'none';
1613 }
1614 );
1615 if (radios.length === 0) {
1616 return;
1617 }
1618 let currentIndex = radios.indexOf(currentEl);
1619 if (currentIndex === -1) {
1620 currentIndex = 0;
1621 }
1622 let targetIndex;
1623 switch (action) {
1624 case 'prev':
1625 targetIndex = (currentIndex - 1 + radios.length) % radios.length;
1626 break;
1627 case 'next':
1628 targetIndex = (currentIndex + 1) % radios.length;
1629 break;
1630 case 'first':
1631 targetIndex = 0;
1632 break;
1633 case 'last':
1634 targetIndex = radios.length - 1;
1635 break;
1636 default:
1637 return;
1638 }
1639 let targetEl = radios[targetIndex];
1640 if (!targetEl) {
1641 return;
1642 }
1643 let targetValue = targetEl.getAttribute('data-toggle-value');
1644 if (targetValue === null) {
1645 // Fall back to mapping by visible position in control.options.
1646 let visibleOptions = (control.options || []).filter(function (opt) {
1647 return opt.condition === undefined || self.checkControlCondition(opt.condition);
1648 });
1649 if (visibleOptions[targetIndex]) {
1650 targetValue = visibleOptions[targetIndex].value;
1651 }
1652 }
1653 targetEl.focus();
1654 if (targetValue !== null && targetValue !== undefined) {
1655 // Per ARIA radio pattern: arrow keys auto-activate.
1656 let opt = (control.options || []).find(function (o) { return String(o.value) === String(targetValue); }) || {};
1657 let doProcess = opt.checkExtension !== undefined ? self.checkExtensionActive(opt.checkExtension) : true;
1658 self.changeSettingValue(control.id, opt.value !== undefined ? opt.value : targetValue, doProcess);
1659 }
1660 },
1661
1662 changeSettingValue : function(settingID, value, doProcess = true, ajaxAction = false) {
1663 var self = this,
1664 dateRangeElements = [
1665 'daterangefromtype',
1666 'daterangefromspecific',
1667 'daterangefromrelative',
1668 'daterangeuntiltype',
1669 'daterangeuntilspecific',
1670 'daterangeuntilrelative'
1671 ];
1672 if( dateRangeElements.includes(settingID) ){
1673 self.processDateRange();
1674 }
1675
1676 if(settingID == 'feedlayout' && value == 'carousel' && !self.checkExtensionActive('carousel')){
1677 self.viewsActive.extensionsPopupElement = 'carousel';
1678 }else{
1679 if(doProcess){
1680 self.customizerFeedData.settings[settingID] = value;
1681 }
1682 if(settingID === 'showpoststypes' && value === 'all'){
1683 ajaxAction = 'feedFlyPreview';
1684 self.customizerFeedData.settings.type = [
1685 'links',
1686 'events',
1687 'videos',
1688 'photos',
1689 'albums',
1690 'statuses'
1691 ];
1692 }
1693 if(ajaxAction !== false){
1694 self.customizerControlAjaxAction(ajaxAction);
1695 }
1696 var whenToGenerateFeed = [
1697 'layout',
1698 'feedlayout',
1699 'cols',
1700 'colstablet',
1701 'colsmobile',
1702 'nummobile'
1703 ];
1704 if( whenToGenerateFeed.includes( settingID ) ){
1705 self.loadingBar = true;
1706 self.generateMasonryGridHeight('update');
1707 self.reinitCarouselHTML();
1708 setTimeout(function(){
1709 self.processNotification('previewUpdated');
1710 }, 1000)
1711 }
1712 self.checkReinitCarousel(settingID);
1713 }
1714
1715 },
1716
1717
1718 changeSwitcherSettingValue : function(settingID, onValue, offValue, ajaxAction = false) {
1719 var self = this;
1720 self.customizerFeedData.settings[settingID] = self.customizerFeedData.settings[settingID] == onValue ? offValue : onValue;
1721 if(ajaxAction !== false){
1722 self.customizerControlAjaxAction(ajaxAction);
1723 }
1724 self.checkReinitCarousel(settingID);
1725 },
1726
1727 changeCheckboxSectionValue : function(settingID, value, ajaxAction = false){
1728 var self = this;
1729 var settingValue = self.customizerFeedData.settings[settingID];
1730 if(!Array.isArray(settingValue) && settingID == 'type'){
1731 settingValue = [settingValue];
1732 }
1733 if(settingValue.includes(value)){
1734 settingValue.splice(settingValue.indexOf(value),1);
1735 }else{
1736 settingValue.push(value);
1737 }
1738 if(settingID == 'type'){
1739 self.processFeedTypesSources( settingValue );
1740 }
1741 //settingValue = (settingValue.length == 1 && settingID == 'type') ? settingValue[0] : settingValue;
1742 self.customizerFeedData.settings[settingID] = settingValue;
1743 if(ajaxAction !== false){
1744 self.customizerControlAjaxAction(ajaxAction);
1745 }
1746 if(settingID == 'include'){
1747 setTimeout(function(){
1748 self.generateMasonryGridHeight('update');
1749 },250);
1750 }
1751 event.stopPropagation()
1752
1753 },
1754 checkboxSectionValueExists : function(settingID, value){
1755 var self = this;
1756 var settingValue = self.customizerFeedData.settings[settingID];
1757 return settingValue.includes(value) ? true : false;
1758 },
1759
1760 /**
1761 * Check Control Condition
1762 *
1763 * @since 4.0
1764 */
1765 checkControlCondition : function(conditionsArray = [], checkExtensionActive = false, checkExtensionActiveDimmed = false){
1766 var self = this,
1767 isConditionTrue = 0;
1768 Object.keys(conditionsArray).forEach(function(condition, index){
1769 if(conditionsArray[condition].indexOf(self.customizerFeedData.settings[condition]) !== -1)
1770 isConditionTrue += 1
1771 });
1772 var extensionCondition = checkExtensionActive != undefined && checkExtensionActive != false ? self.checkExtensionActive(checkExtensionActive) : true,
1773 extensionCondition = checkExtensionActiveDimmed != undefined && checkExtensionActiveDimmed != false && !self.checkExtensionActive(checkExtensionActiveDimmed) ? false : extensionCondition;
1774
1775 return (isConditionTrue == Object.keys(conditionsArray).length) ? ( extensionCondition ) : false;
1776 },
1777
1778 /**
1779 * Check Color Override Condition
1780 *
1781 * @since 4.0
1782 */
1783 checkControlOverrideColor : function(overrideConditionsArray = []){
1784 var self = this,
1785 isConditionTrue = 0;
1786 overrideConditionsArray.forEach(function(condition, index){
1787 if(self.checkNotEmpty(self.customizerFeedData.settings[condition]) && self.customizerFeedData.settings[condition].replace(/ /gi,'') != '#'){
1788 isConditionTrue += 1
1789 }
1790 });
1791 return (isConditionTrue >= 1) ? true : false;
1792 },
1793
1794 /**
1795 * Show Control
1796 *
1797 * @since 4.0
1798 */
1799 isControlShown : function( control ){
1800 var self = this;
1801 if(control.checkExtension != undefined && control.checkExtension != false && !self.checkExtensionActive(control.checkExtension)){
1802 return self.checkExtensionActive(control.checkExtension);
1803 }
1804
1805 if(control.conditionDimmed != undefined && self.checkControlCondition(control.conditionDimmed) )
1806 return self.checkControlCondition(control.conditionDimmed);
1807 if(control.overrideColorCondition != undefined){
1808 return self.checkControlOverrideColor( control.overrideColorCondition );
1809 }
1810
1811 return ( control.conditionHide != undefined && control.condition != undefined || control.checkExtension != undefined )
1812 ? self.checkControlCondition(control.condition, control.checkExtension)
1813 : true;
1814 },
1815
1816 checkExtensionActive : function(extension){
1817 var self = this;
1818 return self.activeExtensions[extension];
1819 },
1820
1821 expandSourceInfo : function(sourceId){
1822 var self = this;
1823 self.customizerScreens.sourceExpanded = (self.customizerScreens.sourceExpanded === sourceId) ? null : sourceId;
1824 },
1825
1826 resetColor: function(controlId){
1827 this.customizerFeedData.settings[controlId] = '';
1828 },
1829
1830 //Source Active Customizer
1831 isSourceActiveCustomizer : function(source){
1832 var self = this;
1833 return (
1834 Array.isArray(self.customizerFeedData.settings.sources.map) ||
1835 self.customizerFeedData.settings.sources instanceof Object
1836 ) &&
1837 self.customizerScreens.sourcesChoosed.map(s => s.account_id).includes(source.account_id);
1838 //self.customizerFeedData.settings.sources.map(s => s.account_id).includes(source.account_id);
1839 },
1840 //Choose Source From Customizer
1841 selectSourceCustomizer : function(source, isRemove = false){
1842 var self = this,
1843 isMultifeed = (self.activeExtensions['multifeed'] !== undefined && self.activeExtensions['multifeed'] == true),
1844 sourcesListMap = Array.isArray(self.customizerFeedData.settings.sources) || self.customizerFeedData.settings.sources instanceof Object ? self.customizerFeedData.settings.sources.map(s => s.account_id) : [];
1845 if(isMultifeed){
1846 if(sourcesListMap.includes(source.account_id)){
1847 var indexToRemove = self.customizerFeedData.settings.sources.findIndex(src => src.account_id === source.account_id);
1848 self.customizerScreens.sourcesChoosed.splice(indexToRemove, 1);
1849 if(isRemove){
1850 self.customizerFeedData.settings.sources.splice(indexToRemove, 1);
1851 }
1852 }else{
1853 self.customizerScreens.sourcesChoosed.push(source);
1854 }
1855 }else{
1856 self.customizerScreens.sourcesChoosed = (sourcesListMap.includes(source)) ? [] : [source];
1857 }
1858 cffBuilder.$forceUpdate();
1859 },
1860 closeSourceCustomizer : function(){
1861 var self = this;
1862 self.viewsActive['sourcePopup'] = false;
1863 //self.customizerFeedData.settings.sources = self.customizerScreens.sourcesChoosed;
1864 cffBuilder.$forceUpdate();
1865 },
1866 customizerFeedTypePrint : function(){
1867 var self = this,
1868 combinedTypes = self.feedTypes.concat(self.advancedFeedTypes);
1869 result = combinedTypes.filter(function(tp){
1870 return tp.type === self.customizerFeedData.settings.feedtype
1871 });
1872 self.customizerScreens.printedType = result.length > 0 ? result[0] : [];
1873 return result.length > 0 ? true : false;
1874 },
1875 choosedFeedTypeCustomizer : function(feedType){
1876 var self = this, result = false;
1877 if(
1878 (self.viewsActive.feedTypeElement === null && self.customizerFeedData.settings.feedtype === feedType) ||
1879 (self.viewsActive.feedTypeElement !== null && self.viewsActive.feedTypeElement == feedType)
1880 ){
1881 result = true;
1882 }
1883 return result;
1884 },
1885
1886
1887
1888 updateFeedTypeCustomizer : function(){
1889 var self = this;
1890 if (self.viewsActive.feedTypeElement === 'socialwall') {
1891 window.location.href = cff_builder.pluginsInfo.social_wall.settingsPage;
1892 return;
1893 }
1894 self.setType( self.viewsActive.feedTypeElement );
1895
1896 self.customizerFeedData.settings.feedtype = self.viewsActive.feedTypeElement;
1897 self.viewsActive.feedTypeElement = null;
1898 self.viewsActive.feedtypesPopup = false;
1899 self.customizerControlAjaxAction('feedFlyPreview');
1900 cffBuilder.$forceUpdate();
1901 },
1902 updateInputWidth : function(){
1903 this.customizerScreens.inputNameWidth = ((document.getElementById("cff-csz-hd-input").value.length + 6) * 8) + 'px';
1904 },
1905 customizerStyleMaker : function(){
1906 var self = this;
1907 if(self.customizerSidebarBuilder){
1908 self.feedStyle = '';
1909 Object.values(self.customizerSidebarBuilder).map( function(tab) {
1910 self.customizerSectionStyle(tab.sections);
1911 });
1912 return '<style type="text/css">' + self.feedStyle + '</style>';
1913 }
1914 return false;
1915 },
1916
1917 /**
1918 * Get Feed Preview Global CSS Class
1919 *
1920 * @since 4.0
1921 * @return String
1922 */
1923 feedPreviewCssClasses : function(){
1924 var self = this,
1925 colorScheme = self.customizerFeedData.settings.colorpalette;
1926
1927 },
1928
1929 customizerSectionStyle : function(sections){
1930 var self = this;
1931 Object.values(sections).map(function(section){
1932 if(section.controls){
1933 Object.values(section.controls).map(function(control){
1934 self.returnControlStyle(control);
1935 });
1936 }
1937 if(section.nested_sections){
1938 self.customizerSectionStyle(section.nested_sections);
1939 Object.values(section.nested_sections).map(function(nestedSections){
1940 Object.values(nestedSections.controls).map(function(nestedControl){
1941 if(nestedControl.section){
1942 self.customizerSectionStyle(nestedControl);
1943 }
1944 });
1945 });
1946 }
1947 });
1948 },
1949 returnControlStyle : function( control ){
1950 var self = this;
1951 if(control.style){
1952 Object.entries(control.style).map( function(css) {
1953 var condition = control.condition != undefined || control.checkExtension != undefined ? self.checkControlCondition(control.condition, control.checkExtension) : true;
1954 if( condition ){
1955 self.feedStyle +=
1956 css[0] + '{' +
1957 css[1].replace("{{value}}", self.customizerFeedData.settings[control.id]) +
1958 '}';
1959 }
1960 });
1961 }
1962 },
1963
1964 /**
1965 * Check Reinit Carousel
1966 *
1967 * @since 4.0
1968 */
1969 checkReinitCarousel : function(settingID){
1970 var self = this,
1971 whenToReiniCarousel = [
1972 'carouselheight',
1973 'carouseldesktop_cols',
1974 'carouselmobile_cols',
1975 'carouselnavigation',
1976 'carouselpagination',
1977 'carouselautoplay',
1978 'carouselinterval',
1979 'reviewshidenotext',
1980 'hidenegative',
1981 'reviewsrated'
1982 ];
1983 if( whenToReiniCarousel.includes( settingID ) ){
1984 self.reinitCarouselHTML();
1985 }
1986 },
1987
1988
1989 /**
1990 * Customizer Control Ajax
1991 * Some of the customizer controls need to perform Ajax
1992 * Calls in order to update the preview
1993 *
1994 * @since 4.0
1995 */
1996 customizerControlAjaxAction : function( actionType ){
1997 var self = this;
1998 switch (actionType) {
1999 case 'feedFlyPreview':
2000 self.loadingBar = true;
2001 var previewFeedData = {
2002 action : 'cff_feed_saver_manager_fly_preview',
2003 feedID : self.customizerFeedData.feed_info.id,
2004 previewSettings : self.customizerFeedData.settings,
2005 };
2006 self.ajaxPost(previewFeedData, function(_ref){
2007 var data = _ref.data;
2008 if( data !== false ){
2009 self.disableJQueryNodes();
2010 self.customizerFeedData.posts = data.posts;
2011 self.customizerFeedData.header = data.header;
2012 self.processNotification("previewUpdated");
2013 }else{
2014 self.processNotification("unkownError");
2015 }
2016 setTimeout(function(){
2017 self.reinitCarouselHTML();
2018 self.generateMasonryGridHeight('update');
2019 }, 150);
2020 });
2021 break;
2022 case 'feedPreviewRender':
2023 setTimeout(function(){
2024 self.generateMasonryGridHeight('update');
2025 }, 150);
2026 break;
2027 }
2028 },
2029
2030 /**
2031 * Process & Re-Order Post Array for Masonry layouts
2032 *
2033 * @since 4.0
2034 *
2035 * @return Array
2036 */
2037 processPostArrayDisplay : function(postsArray){
2038 var self = this,
2039 feedlayout = self.customizerFeedData.settings.feedlayout,
2040 feedtype = self.customizerFeedData.settings.feedtype,
2041 currentDevice = self.customizerScreens.previewScreen;
2042 if(feedlayout === 'masonry'){
2043 var colsNumber = 1;
2044 switch (currentDevice) {
2045 case 'desktop':
2046 colsNumber = self.customizerFeedData.settings.cols;
2047 break;
2048 case 'tablet':
2049 colsNumber = self.customizerFeedData.settings.colstablet;
2050 break;
2051 case 'mobile':
2052 colsNumber = self.customizerFeedData.settings.colsmobile;
2053 break;
2054 }
2055 colsNumber = parseInt(colsNumber);
2056 if(colsNumber > 1){
2057 var reorderedPostsArray = [],
2058 counter = 0;
2059 while(counter < colsNumber) {
2060 for(var i = 0; i < postsArray.length; i += colsNumber) {
2061 var elementIndex = parseInt(i) + parseInt(counter);
2062 var _val = postsArray[elementIndex];
2063 if (_val !== undefined)
2064 reorderedPostsArray.push(_val);
2065 }
2066 counter++;
2067 }
2068 postsArray = reorderedPostsArray;
2069 }
2070 }
2071 return postsArray;
2072 },
2073
2074 /**
2075 * Generate the Feed Posts Height For Masonry & Grid Layouts
2076 *
2077 * @since 4.0
2078 */
2079 generateCarouselSettings : function(){
2080 var self = this,
2081 carouselElement = jQuery('.cff-preview-posts-list-ctn'),
2082 customizerSettings = self.customizerFeedData.settings,
2083 currentDevice = self.customizerScreens.previewScreen;
2084 if(customizerSettings.feedlayout === 'carousel' && self.activeExtensions['carousel'] == true){
2085 carouselElement.addClass('cff-carousel');
2086 var carouselHeightInput = customizerSettings.carouselheight,
2087 carouselMobileCols = parseInt(customizerSettings.carouselmobile_cols),
2088 carouselCols = (currentDevice == 'desktop') ? parseInt(customizerSettings.carouseldesktop_cols) : carouselMobileCols,
2089 carouselArrowsInput = parseInt(customizerSettings.carouselnavigation),
2090 carouselArrows = true,
2091 carouselPag = self.valueIsEnabled(customizerSettings.carouselpagination) ? true : false,
2092 carouselautoplay = self.valueIsEnabled(customizerSettings.carouselautoplay) ? true : false,
2093 carouselTime = customizerSettings.carouselinterval,
2094 afterUpdate = true;
2095 //afterInit = cffShowCarousel,
2096 singleItem = false,
2097 autoHeight = false;
2098 if(customizerSettings.carouselheight == 'autoexpand'){
2099 singleItem = true;
2100 autoHeight = true;
2101 carouselCols = 1;
2102 carouselMobileCols = 1;
2103 }
2104
2105
2106 var carouselSettings = {
2107 items: carouselCols,
2108 itemsDesktop: [1199, carouselCols],
2109 itemsDesktopSmall: false,
2110 itemsTablet: false,
2111 itemsTabletSmall: false,
2112 itemsMobile: [479, carouselMobileCols],
2113 navigation: carouselArrows,
2114 navigationText: ['<i class="fa fa-chevron-left"></i>','<i class="fa fa-chevron-right"></i>'],
2115 dots: carouselPag,
2116 autoplay:carouselautoplay,
2117 autoplayTimeout:carouselTime,
2118 stopOnHover: true,
2119 singleItem : singleItem,
2120 autoHeight : autoHeight,
2121 margin: 20,
2122
2123 // afterUpdate: afterUpdate,
2124 // afterInit: afterInit
2125 };
2126 carouselElement.owlCarousel(carouselSettings);
2127 carouselElement.on('changed.owl.carousel',function(){
2128 self.generateNavigationCarousel(customizerSettings, carouselElement);
2129 })
2130 self.generateCarouselHTMLAttributes(carouselElement);
2131
2132 }
2133 },
2134
2135 /**
2136 * Generate Carousel HTML Attributes
2137 *
2138 * @since 4.0
2139 */
2140 generateCarouselHTMLAttributes : function(carouselElement){
2141 var self = this,
2142 customizerSettings = self.customizerFeedData.settings;
2143 carouselElement.attr({
2144 'data-navigation' : customizerSettings.carouselnavigation
2145 });
2146 self.generateNavigationCarousel(customizerSettings, carouselElement);
2147 },
2148
2149 /**
2150 * Generate Carousel Navigation
2151 *
2152 * @since 4.0
2153 */
2154 generateNavigationCarousel : function(customizerSettings, carouselElement){
2155 if(customizerSettings.carouselnavigation == 'below'){
2156 var $navigation = carouselElement.find('.owl-dots');
2157 carouselElement.find('.owl-nav').remove();
2158 if($navigation.children('.owl-prev').length <= 0){
2159 $navigation.prepend('<button type="button" role="presentation" class="owl-prev"><span aria-label="Previous">‹</span></button>');
2160 }
2161 if($navigation.children('.owl-next').length <= 0){
2162 $navigation.append('<button type="button" role="presentation" class="owl-next"><span aria-label="Next">›</span></button>');
2163 }
2164
2165 }
2166 },
2167
2168 /**
2169 * Disable JQuery Plugin Nodes
2170 *
2171 * @since 4.0
2172 */
2173 disableJQueryNodes : function(){
2174 var self = this,
2175 customizerSettings = self.customizerFeedData.settings,
2176 carouselElement = jQuery('.cff-preview-posts-list-ctn');
2177 if(self.activeExtensions['carousel'] == true){
2178 carouselElement.owlCarousel('destroy');
2179 carouselElement.removeClass('cff-carousel');
2180 carouselElement.removeAttr('data-navigation');
2181 }
2182 },
2183
2184 /**
2185 * Reinit Carousel Element
2186 *
2187 * @since 4.0
2188 */
2189 reinitCarouselHTML : function(){
2190 var self = this,
2191 customizerSettings = self.customizerFeedData.settings,
2192 carouselElement = jQuery('.cff-preview-posts-list-ctn');
2193 if(self.activeExtensions['carousel'] == true){
2194 carouselElement.owlCarousel('destroy');
2195 carouselElement.removeClass('cff-carousel');
2196 carouselElement.removeAttr('data-navigation');
2197 if(customizerSettings.feedlayout === 'carousel'){
2198 self.loadingBar = true;
2199 setTimeout(function(){
2200 self.generateCarouselSettings();
2201 self.processNotification('carouselLayoutUpdated');
2202 }, 150)
2203 }
2204 }
2205
2206 },
2207
2208 /**
2209 * Generate the Feed Posts Height For Masonry & Grid Layouts
2210 *
2211 * @since 4.0
2212 */
2213 generateMasonryGridHeight : function(typeAppend){
2214 var self = this,
2215 feedlayout = self.customizerFeedData.settings.feedlayout,
2216 feedtype = self.customizerFeedData.settings.feedtype,
2217 currentDevice = self.customizerScreens.previewScreen;
2218 //Masonry Layout
2219 if(feedlayout === 'masonry'){
2220 var $masonryParent = jQuery('.cff-preview-posts-masonry').isotope({
2221 itemSelector: '.cff-post-item-ctn',
2222 percentPosition: true,
2223 masonry: {
2224 columnWidth: '.cff-post-item-ctn'
2225 }
2226 });
2227 // layout Isotope after each image loads
2228 $masonryParent.imagesLoaded().progress( function() {
2229 if(typeAppend == 'update'){
2230 $masonryParent.isotope('reloadItems').isotope();
2231 }else{
2232 $masonryParent.isotope('layout');
2233 }
2234 });
2235
2236 }else{
2237 if(jQuery('.cff-preview-posts-list-ctn').data('isotope')){
2238 jQuery('.cff-preview-posts-list-ctn').isotope('destroy')
2239 }
2240 }
2241
2242 //Grid Layout
2243 if(feedlayout === 'grid'){
2244 var grid = document.getElementsByClassName('cff-preview-posts-grid')[0];
2245 if( grid ) {
2246 var allItems = document.querySelectorAll('.cff-post-item-ctn');
2247 if( allItems ) {
2248 var plusHeight = (feedtype == 'videos' || feedtype == 'albums') ? 70 : 0;
2249 allItems.forEach( function(item, index) {
2250 item.style.height = parseFloat(item.getBoundingClientRect().width + plusHeight) + 'px';
2251 item.style.gridRowEnd = 'unset';
2252 });
2253 }
2254 }
2255 }
2256
2257 if(feedlayout == 'carousel' && feedtype == 'singlealbum'){
2258 var allItems = document.querySelectorAll('.owl-item');
2259 if( allItems ) {
2260 allItems.forEach( function(item, index) {
2261 item.style.height = item.getBoundingClientRect().width + 'px';
2262 item.style.gridRowEnd = 'unset';
2263 });
2264 }
2265 }
2266 },
2267
2268
2269 /**
2270 * Get Feed Columns Depending on the Settings
2271 *
2272 * @since 4.0
2273 *
2274 * @return String | Bool
2275 */
2276 getFeedColumns : function(){
2277 var self = this,
2278 feedlayout = self.customizerFeedData.settings.feedlayout,
2279 feedtype = self.customizerFeedData.settings.feedtype,
2280 currentDevice = self.customizerScreens.previewScreen;
2281
2282 if(feedlayout === 'masonry' || (feedlayout === 'grid' && feedtype !== 'timeline')){
2283 switch (currentDevice) {
2284 case 'desktop':
2285 return self.customizerFeedData.settings.cols;
2286 case 'tablet':
2287 return self.customizerFeedData.settings.colstablet;
2288 case 'mobile':
2289 return self.customizerFeedData.settings.colsmobile;
2290 }
2291 }
2292 return false;
2293 },
2294
2295 /**
2296 * Toggle Comment Section
2297 *
2298 * @since 4.0
2299 */
2300 toggleCommentSection : function(postID){
2301 var self = this;
2302 if(self.showedCommentSection.includes(postID)){
2303 self.showedCommentSection.splice(self.showedCommentSection.indexOf(postID), 1);
2304 }else{
2305 self.showedCommentSection.push(postID);
2306 }
2307 setTimeout(function(){
2308 self.generateMasonryGridHeight('update');
2309 }, 100)
2310 cffBuilder.$forceUpdate();
2311 },
2312
2313 /**
2314 * Ajax Action : Save Feed Settings
2315 *
2316 * @since 4.0
2317 */
2318 saveFeedSettings : function(){
2319 var self = this,
2320 sources = [],
2321 updateFeedData = {
2322 action : 'cff_feed_saver_manager_builder_update',
2323 update_feed : 'true',
2324 feed_id : self.customizerFeedData.feed_info.id,
2325 feed_name : self.customizerFeedData.feed_info.feed_name,
2326 settings : self.customizerFeedData.settings,
2327 sources : []
2328 };
2329
2330 if(self.customizerFeedData.settings.sources.length > 0){
2331 self.customizerFeedData.settings.sources.forEach(function(source){
2332 updateFeedData.sources.push(source.account_id);
2333 })
2334 }
2335 self.loadingBar = true;
2336 self.ajaxPost(updateFeedData, function(_ref){
2337 var data = _ref.data;
2338 if(data && data.success === true){
2339 self.processNotification('feedSaved');
2340 self.customizerFeedDataInitial = self.customizerFeedData;
2341 }else{
2342 self.processNotification('feedSavedError');
2343 }
2344 });
2345 cffBuilder.$forceUpdate();
2346 },
2347
2348 /**
2349 * Ajax Action : Clear Single Feed Cache
2350 * Update Feed Preview Too
2351 * @since 4.0
2352 */
2353 clearSingleFeedCache : function(){
2354 var self = this,
2355 sources = [],
2356 clearFeedData = {
2357 action : 'cff_feed_saver_manager_clear_single_feed_cache',
2358 feedID : self.customizerFeedData.feed_info.id,
2359 previewSettings : self.customizerFeedData.settings,
2360 };
2361 self.loadingBar = true;
2362 self.ajaxPost(clearFeedData, function(_ref){
2363 var data = _ref.data;
2364 if( data !== false ){
2365 self.customizerFeedData.posts = data.posts;
2366 self.customizerFeedData.header = data.header;
2367 self.processNotification('cacheCleared');
2368 }else{
2369 self.processNotification("unkownError");
2370 }
2371 })
2372 cffBuilder.$forceUpdate();
2373 },
2374
2375 /**
2376 * Clear & Reset Color Override
2377 *
2378 * @since 4.0
2379 */
2380 resetColorOverride : function(settingID){
2381 this.customizerFeedData.settings[settingID] = '';
2382 },
2383
2384 /**
2385 * Print Story
2386 *
2387 * @since 4.0
2388 *
2389 * @return String
2390 */
2391 printStory : function(singlePost){
2392 var self = this,
2393 authorName = self.hasOwnNestedProperty(singlePost, 'from.name') ? singlePost.from.name : null,
2394 postStory = self.hasOwnNestedProperty(singlePost, 'story') && authorName != null ? singlePost.story.replace(authorName, '') : null;
2395 return postStory;
2396 },
2397
2398
2399 /**
2400 * Format & Print Date
2401 *
2402 * @since 4.0
2403 *
2404 * @return String
2405 */
2406 printDate : function( postDate, eventDate = false ){
2407 var self = this,
2408 originalDate = Date.parse(postDate) / 1000,
2409 dateOffset = new Date(),
2410 offsetTimezone = dateOffset.getTimezoneOffset(),
2411 periods = [
2412 self.translatedText.secondText,
2413 self.translatedText.minuteText,
2414 self.translatedText.hourText,
2415 self.translatedText.dayText,
2416 self.translatedText.weekText,
2417 self.translatedText.monthText,
2418 self.translatedText.yearText
2419 ],
2420 periodsPlural = [
2421 self.translatedText.secondsText,
2422 self.translatedText.minutesText,
2423 self.translatedText.hoursText,
2424 self.translatedText.daysText,
2425 self.translatedText.weeksText,
2426 self.translatedText.monthsText,
2427 self.translatedText.yearsText
2428 ],
2429 lengths = ["60","60","24","7","4.35","12","10"],
2430 now = dateOffset.getTime() / 1000,
2431 newTime = originalDate + offsetTimezone,
2432 printDate = '',
2433 dateFortmat = eventDate ? self.customizerFeedData.settings.eventdateformat : self.customizerFeedData.settings.dateformat,
2434 agoText = self.translatedText.agoText,
2435 difference = null,
2436 formatsChoices = {
2437 '2' : 'F jS, g:i a',
2438 '3' : 'F jS',
2439 '4' : 'D F jS',
2440 '5' : 'l F jS',
2441 '6' : 'D M jS, Y',
2442 '7' : 'l F jS, Y',
2443 '8' : 'l F jS, Y - g:i a',
2444 '9' : "l M jS, 'y",
2445 '10' : 'm.d.y',
2446 '11' : 'm/d/y',
2447 '12' : 'd.m.y',
2448 '13' : 'd/m/y',
2449 '14' : 'd-m-Y, G:i',
2450 '15' : 'jS F Y, G:i',
2451 '16' : 'd M Y, G:i',
2452 '17' : 'l jS F Y, G:i',
2453 '18' : 'm.d.y - G:i',
2454 '19' : 'd.m.y - G:i'
2455 };
2456
2457 if(formatsChoices.hasOwnProperty(dateFortmat)){
2458 printDate = date_i18n( formatsChoices[dateFortmat], newTime );
2459 }else if(dateFortmat == 'custom'){
2460 printDate = date_i18n( self.customizerFeedData.settings.datecustom, newTime );
2461
2462 }
2463 else{
2464 if( now > originalDate ) {
2465 difference = now - originalDate;
2466
2467 }else{
2468 difference = originalDate - now;
2469 }
2470 for(var j = 0; difference >= lengths[j] && j < lengths.length-1; j++) {
2471 difference /= lengths[j];
2472 }
2473 difference = Math.round(difference);
2474 if(difference != 1) {
2475 periods[j] = periodsPlural[j];
2476 }
2477 printDate = difference + " " + periods[j] + " "+ agoText;
2478 }
2479
2480 return printDate;
2481 },
2482
2483 /**
2484 * Print Event Location
2485 *
2486 * @since 4.0
2487 *
2488 * @return String
2489 */
2490 getEventMapLink : function( place ){
2491 var self = this;
2492 latitude = (self.hasOwnNestedProperty(place,'location.latitude')) ? self.htmlEntities(place.location.latitude) : '',
2493 longitude = (self.hasOwnNestedProperty(place,'location.longitude')) ? self.htmlEntities(place.location.longitude) : '',
2494 locationMap = self.hasOwnNestedProperty(place,'name') ? self.htmlEntities(place.name) : '',
2495 mapUrl = false;
2496 if( self.hasOwnNestedProperty(place, 'location') ){
2497 mapUrl = 'https://maps.google.com/maps?q=' + latitude + ',+' + longitude;
2498 }else if( locationMap.match(/~[0-9]~/) && locationMap.length > 10 ){
2499 mapUrl = 'https://maps.google.com/maps?q='+ location;
2500 }
2501 return mapUrl;
2502 },
2503
2504 /**
2505 * Posts List
2506 *
2507 * @since 4.0
2508 *
2509 * @return Array
2510 */
2511 returnPostList : function(){
2512 var self = this,
2513 customizerSettings = self.customizerFeedData.settings
2514 if(customizerSettings.feedtype == 'reviews'){
2515 return self.reviewsFeedTypeCheck();
2516 }else{
2517 var numberOfPosts = (self.customizerScreens.previewScreen == 'desktop') ? customizerSettings.num : (self.checkNotEmpty(customizerSettings.nummobile) ? customizerSettings.nummobile : customizerSettings.num);
2518 numberOfPosts = self.checkNotEmpty(numberOfPosts) ? numberOfPosts : 0;
2519 return (customizerSettings.feedlayout == 'carousel') ? self.customizerFeedData.posts : self.customizerFeedData.posts.slice(0, numberOfPosts);
2520 }
2521 },
2522
2523 /**
2524 * Create String of Views Rated
2525 *
2526 * @since 4.0
2527 *
2528 * @return Array
2529 */
2530 processReviewsRated : function(){
2531 var self = this,
2532 settings = self.customizerFeedData.settings,
2533 reviewsratedArray = [],
2534 star5 = self.valueIsEnabled(settings.cff_reviews_rated_5) ? reviewsratedArray.push(5) : reviewsratedArray.splice(reviewsratedArray.indexOf(5)),
2535 star4 = self.valueIsEnabled(settings.cff_reviews_rated_4) ? reviewsratedArray.push(4) : reviewsratedArray.splice(reviewsratedArray.indexOf(4)),
2536 star3 = self.valueIsEnabled(settings.cff_reviews_rated_3) ? reviewsratedArray.push(3) : reviewsratedArray.splice(reviewsratedArray.indexOf(3)),
2537 star2 = self.valueIsEnabled(settings.cff_reviews_rated_2) ? reviewsratedArray.push(2) : reviewsratedArray.splice(reviewsratedArray.indexOf(2)),
2538 star1 = self.valueIsEnabled(settings.cff_reviews_rated_1) ? reviewsratedArray.push(1) : reviewsratedArray.splice(reviewsratedArray.indexOf(1));
2539 self.customizerFeedData.settings.reviewsrated = reviewsratedArray.join(',');
2540 return reviewsratedArray;
2541 },
2542
2543
2544 /**
2545 * Check & Process Reviews Feed Type
2546 *
2547 * @since 4.0
2548 *
2549 * @return Array
2550 */
2551 reviewsFeedTypeCheck : function(){
2552 var self = this,
2553 reviewArray = [],
2554 reviewsratedArray = self.processReviewsRated();
2555
2556 self.customizerFeedData.posts.forEach( function(review, index) {
2557 if(
2558 (
2559 self.valueIsEnabled(self.customizerFeedData.settings.reviewshidenotext) && self.checkNotEmpty(review.review_text) == true
2560 )
2561 || !self.valueIsEnabled(self.customizerFeedData.settings.reviewshidenotext)
2562 ){
2563 var hasReviewRating = review.rating != undefined && review.rating != null;
2564 if( ( hasReviewRating && reviewsratedArray.includes(review.rating) ) || !hasReviewRating ){
2565 reviewArray.push({
2566 created_time : review.created_time,
2567 recommendation_type : review.recommendation_type,
2568 message : review.review_text,
2569 from : review.reviewer,
2570 rating : review.rating ? review.rating : undefined
2571 });
2572 }
2573 }
2574 });
2575 return reviewArray;
2576 },
2577
2578
2579 /**
2580 * HTML Entities
2581 *
2582 * @since 4.0
2583 *
2584 * @return String
2585 */
2586 htmlEntities : function (str) {
2587 return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
2588 },
2589
2590 /**
2591 * Check Process Post Image
2592 *
2593 * @since 4.0
2594 */
2595 checkProcessPostImage : function( post ){
2596 var self = this,
2597 showImage = self.customizerFeedData.settings.include.includes('media') && (post.status_type == 'added_photos' || post.status_type == 'created_event' || self.customizerFeedData.settings.feedtype == 'events');
2598 imageExist = self.hasOwnNestedProperty(post, 'full_picture') ? true : ( self.hasOwnNestedProperty(post , 'attachments.data') && post.attachments.data[0] && post.attachments.data[0].media ? true : false);
2599 if( self.customizerFeedData.settings.feedtype == 'events' ){
2600 imageExist = self.hasOwnNestedProperty(post, 'cover.source');
2601 }
2602 return imageExist && showImage;
2603 },
2604
2605 /**
2606 * Process Post Image Source
2607 *
2608 * @since 4.0
2609 */
2610 processPostImageSrc : function( post ){
2611 var self = this;
2612 if(self.customizerFeedData.settings.feedtype == 'events' && self.hasOwnNestedProperty(post, 'cover.source') ){
2613 return post.cover.source;
2614 }
2615 return self.hasOwnNestedProperty(post, 'full_picture') ? post.full_picture : post.attachments.data[0].media.image.src
2616 },
2617
2618 /**
2619 * Process Video LightBox
2620 *
2621 * @since 4.0
2622 */
2623 processPostVideoSrc : function( singlePost ){
2624 var self = this,
2625 videoInfo = self.processIframeAndLinkAndVideo( singlePost ),
2626 videoSource = null;
2627 if( self.hasOwnNestedProperty( videoInfo, 'type' ) ){
2628 switch (videoInfo.type) {
2629 case 'embed':
2630 videoSource = self.hasOwnNestedProperty(videoInfo, 'url') ? videoInfo.url : null;
2631 break;
2632 case 'video':
2633 videoSource = self.hasOwnNestedProperty(videoInfo, 'args.unshimmedUrl') ? 'https://www.facebook.com/v2.3/plugins/video.php?href=' + videoInfo.args.unshimmedUrl : null;
2634 break;
2635 }
2636 }
2637 return videoSource;
2638 },
2639
2640
2641
2642 /**
2643 * Print Album Attachment Number
2644 *
2645 * @since 4.0
2646 */
2647 printAlbumImageNumberOverlay : function(subAttachmentsArray){
2648 return '+' + (subAttachmentsArray.length - 3).toString();
2649 },
2650
2651 /**
2652 * Print Element Overlay
2653 *
2654 * @since 4.0
2655 */
2656 getPostElementOverlay : function( singlePost ){
2657 var self = this,
2658 postType = self.getPostTypeTimeline(singlePost),
2659 activeImage = null,
2660 videoSource = null,
2661 domBody = document.getElementsByTagName("body")[0];
2662 /*
2663 videos
2664 links
2665 photos
2666 albums
2667 events
2668 */
2669 switch (postType) {
2670 case 'photos':
2671 activeImage = self.processPostImageSrc(singlePost);
2672 break;
2673 case 'albums':
2674 activeImage = self.processPostImageSrc(singlePost);
2675 break;
2676 case 'events':
2677 activeImage = self.processPostImageSrc(singlePost);
2678 break;
2679 case 'videos' :
2680 postType = 'videos';
2681 videoSource = self.processPostVideoSrc(singlePost);
2682 break;
2683 }
2684 if(self.customizerFeedData.settings.feedtype == 'videos'){
2685 postType = 'embed_videos';
2686 videoSource = singlePost.embed_html;
2687 }
2688
2689 self.lightBox = {
2690 visibility : 'shown',
2691 type : postType,
2692 post : singlePost,
2693 activeImage : activeImage,
2694 albumIndex : 0,
2695 videoSource : videoSource
2696 };
2697
2698 document.body.scrollTop = 0;
2699 document.documentElement.scrollTop = 0;
2700 domBody.classList.add("no-overflow");
2701 cffBuilder.$forceUpdate();
2702
2703 },
2704
2705
2706 /**
2707 * Print Element Overlay
2708 *
2709 * @since 4.0
2710 */
2711 hideLightBox : function(){
2712 var self = this,
2713 domBody = document.getElementsByTagName("body")[0];
2714 domBody.classList.remove("no-overflow");
2715 self.lightBox = {
2716 visibility : 'hidden',
2717 type : null,
2718 post : null,
2719 activeImage : null,
2720 albumIndex : 0,
2721 videoSource : null
2722 };
2723 self.dummyLightBoxData.visibility = 'hidden';
2724 cffBuilder.$forceUpdate();
2725 },
2726
2727 /**
2728 * Switch Album Image onLick
2729 *
2730 * @since 4.0
2731 */
2732 switchLightboxAlbumImage : function(imageSource, imageIndex){
2733 var self = this;
2734 self.lightBox.activeImage = imageSource;
2735 self.lightBox.albumIndex = imageIndex;
2736 cffBuilder.$forceUpdate();
2737 },
2738
2739 /**
2740 * Navigate Album Image
2741 * Next / Previous
2742 * @since 4.0
2743 */
2744 navigateLightboxAlbumImage : function(navType, images){
2745 var self = this,
2746 activeIndex = (navType == 'prev') ? ( self.lightBox.albumIndex === 0 ? images.length - 1 : self.lightBox.albumIndex - 1 ) : (self.lightBox.albumIndex === images.length - 1 ? 0 : self.lightBox.albumIndex + 1 );
2747 self.lightBox.albumIndex = activeIndex;
2748 self.lightBox.activeImage = images[activeIndex].media.image.src;
2749 cffBuilder.$forceUpdate();
2750 },
2751
2752 /**
2753 * Print Post Text
2754 *
2755 * @since 4.0
2756 *
2757 * @return String
2758 */
2759 printPostText : function( post, fullText = false ){
2760 var self = this,
2761 postText = post.message ? post.message : (post.description ? post.description : ''),
2762 postText = ( !self.checkNotEmpty(postText) && self.getPostTypeTimeline(post) == 'links' && self.hasOwnNestedProperty( self.processIframeAndLinkAndVideo( post ), 'args.title' ) ) ?
2763 self.processIframeAndLinkAndVideo( post ).args.title : postText,
2764
2765 //postVideoEmbed = self.processIframeAndLink( post, postText ),
2766 postText = (!fullText && postText != null) ? postText.substring(0, self.customizerFeedData.settings.textlength) : postText,
2767 postTags = post.message_tags ? post.message_tags : null,
2768 postText = ( !self.valueIsEnabled(self.customizerFeedData.settings.textlink) ) ? self.processPostTags( self.processPostUrls( self.processNewLine( postText ) ), postTags ) : '<a href="https://www.facebook.com/'+post.id+'" target="_blank">' + postText + '</a>';
2769 return postText;
2770 },
2771
2772 /**
2773 * Return Tags Links for Post
2774 *
2775 * @since 4.0
2776 *
2777 * @return String
2778 */
2779 processPostTags : function( postText, postTags ){
2780 if(postTags !== null){
2781 postTags.forEach( function( singleTag ) {
2782 var regEx = new RegExp(singleTag.name, "ig");
2783 postText = postText.replace(regEx, '<a href="https://facebook.com/' + singleTag.id + '" target="_blank" rel="nofollow">' + singleTag.name + '</a>');
2784 });
2785 }
2786 return postText;
2787 },
2788
2789 /**
2790 * Return Tags Links for Post
2791 *
2792 * @since 4.0
2793 *
2794 * @return String
2795 */
2796 processPostUrls: function( postText ){
2797 var replacedText,
2798 httpPattern,
2799 wwwPattern,
2800 mailtoPattern;
2801 httpPattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
2802 replacedText = postText.replace(httpPattern, '<a href="$1" target="_blank">$1</a>');
2803
2804 wwwPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
2805 replacedText = replacedText.replace(wwwPattern, '$1<a href="http://$2" target="_blank">$2</a>');
2806
2807 mailtoPattern = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
2808 replacedText = replacedText.replace(mailtoPattern, '<a href="mailto:$1">$1</a>');
2809
2810 return replacedText
2811 },
2812
2813 /**
2814 * Process New Line Break
2815 *
2816 * @since 4.0
2817 *
2818 * @return String
2819 */
2820 processNewLine : function( postText ){
2821 return postText.replace(/(?:\r\n|\r|\n)/g, '<br />');
2822 },
2823
2824 /**
2825 * Create iFrame & External Link & Video
2826 *
2827 * @since 4.0
2828 *
2829 * @return array
2830 */
2831 processIframeAndLinkAndVideo : function( post ){
2832 var self = this,
2833 postText = post.message ? post.message : (post.description ? post.description : ''),
2834 videoOrLink = self.processVideoAndLink( post );
2835
2836 if( videoOrLink != false && self.hasOwnNestedProperty(videoOrLink, 'args.unshimmedUrl') && videoOrLink.args.unshimmedUrl != null){
2837 //Youtube Process
2838 var regExpYoutube = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/,
2839 matchYoutube = videoOrLink.args.unshimmedUrl.match(regExpYoutube),
2840 youtubeID = (matchYoutube && matchYoutube[2].split(' ')[0].length === 11) ? matchYoutube[2].split(' ')[0] : null;
2841
2842 //Vimeo Process
2843 var regExpVimeo = /vimeo.*\/(\d+)/i ,
2844 matchVimeo = regExpVimeo.exec( videoOrLink.args.unshimmedUrl ),
2845 vimeoID = (matchVimeo && matchVimeo[1]) ? matchVimeo[1] : null;
2846
2847 //Soundcloud Process
2848 const regExpSoundCloud = /^.*(?:(https?):\/\/)?(?:(?:www|m)\.)?(soundcloud\.com|snd\.sc)\/(.*).*/,
2849 matchSoundCloud = videoOrLink.args.unshimmedUrl.match(regExpSoundCloud),
2850 soundCloudUrl = (matchSoundCloud && matchSoundCloud[2]) ? matchSoundCloud[3].split(' ')[0] : null;
2851
2852 //Spotify Process
2853 var regExpSpotify = /^.*((open|play)\.spotify\.com\/)([^#&?]*).*/,
2854 matchSpotify = videoOrLink.args.unshimmedUrl.match(regExpSpotify);
2855 spotifyUrl = (matchSpotify && matchSpotify[2]) ? matchSpotify[3].split(' ')[0] : null;
2856
2857 if(youtubeID != null){
2858 return {
2859 'type' : 'embed',
2860 'url' : 'https://www.youtube.com/embed/' + youtubeID,
2861 'site' : 'video'
2862 };
2863 }else if( vimeoID != null ){
2864 return {
2865 'type' : 'embed',
2866 'url' : '//player.vimeo.com/video/'+vimeoID,
2867 'site' : 'video'
2868 };
2869 }else if(soundCloudUrl != null){
2870 return {
2871 'type' : 'embed',
2872 'url' : 'https://w.soundcloud.com/player/?url=https://soundcloud.com/'+soundCloudUrl+'&amp;auto_play=false&amp;hide_related=true&amp;show_comments=false&amp;show_user=true&amp;show_reposts=false&amp;visual=false',
2873 'site' : 'soundcloud'
2874 };
2875 }else if( spotifyUrl != null){
2876 return {
2877 'type' : 'embed',
2878 'url' : 'https://open.spotify.com/embed/'+spotifyUrl,
2879 'site' : 'spotify'
2880 };
2881 }
2882 }
2883
2884 return videoOrLink;
2885 },
2886
2887
2888 /**
2889 * Process Video & External Link
2890 *
2891 * @since 4.0
2892 *
2893 * @return array
2894 */
2895 processVideoAndLink : function( post ){
2896 var self = this;
2897 if( self.hasOwnNestedProperty(post, 'attachments.data') && post.attachments.data[0] ){
2898 if( post.attachments.data[0] && ( post.attachments.data[0].media_type === 'link' || post.attachments.data[0].media_type === 'video' ) ){
2899 var dataObject = post.attachments.data[0];
2900 switch (dataObject.media_type) {
2901 case 'video':
2902 var domain = (self.hasOwnNestedProperty( dataObject, 'unshimmed_url')) ? (new URL(dataObject.unshimmed_url)).hostname : null;
2903 return {
2904 'type' : 'video',
2905 'args' : {
2906 'title' : self.hasOwnNestedProperty( dataObject, 'title' ) ? dataObject.title : null,
2907 'description' : self.hasOwnNestedProperty( dataObject, 'description') ? dataObject.description : null,
2908 'source' : self.hasOwnNestedProperty( dataObject, 'media.source') ? dataObject.media.source : null,
2909 'poster' : self.hasOwnNestedProperty( dataObject, 'media.image.src') ? dataObject.media.image.src : null,
2910 'unshimmedUrl' : self.hasOwnNestedProperty( dataObject, 'unshimmed_url') ? dataObject.unshimmed_url : null,
2911 'domain' : domain
2912 }
2913 };
2914 case 'link':
2915 var domain = (self.hasOwnNestedProperty( dataObject, 'unshimmed_url')) ? (new URL(dataObject.unshimmed_url)).hostname : null;
2916 return {
2917 'type' : 'link',
2918 'args' : {
2919 'title' : self.hasOwnNestedProperty( dataObject, 'title' ) ? dataObject.title : null,
2920 'description' : self.hasOwnNestedProperty( dataObject, 'description') ? dataObject.description : null,
2921 'poster' : self.hasOwnNestedProperty( post, 'full_picture') ? post.full_picture : null,
2922 'unshimmedUrl' : self.hasOwnNestedProperty( dataObject, 'unshimmed_url') ? dataObject.unshimmed_url : null,
2923 'domain' : domain
2924 }
2925 };
2926 }
2927 }
2928 }else if(post.embed_html){
2929 return {
2930 'type' : 'video',
2931 'args' : {
2932 'title' : self.hasOwnNestedProperty( post, 'title' ) ? post.title : null,
2933 'source' : self.hasOwnNestedProperty( post, 'source') ? post.source : null,
2934 'poster' : self.hasOwnNestedProperty( post, 'format') ? post.format[post.format.length - 1].picture : null,
2935 'unshimmedUrl' : self.hasOwnNestedProperty( post, 'from.id') && self.hasOwnNestedProperty( post, 'id') ? 'https://www.facebook.com/'+post.from.id+'/videos/'+ post.id +'/' : null
2936 }
2937 };
2938 }
2939
2940 return false;
2941 },
2942
2943 /**
2944 * Get Post Type
2945 *
2946 * @since 4.0
2947 *
2948 * @return string
2949 */
2950 getPostTypeTimeline : function( post ){
2951 var self = this,
2952 postType = (post.message) ? 'statuses' : (post.description ? 'statuses' : 'empty');
2953 if( self.hasOwnNestedProperty(post, 'attachments.data') && post.attachments.data[0] ){
2954 if( post.attachments.data[0].media_type ){
2955 switch (post.attachments.data[0].media_type) {
2956 case 'video':
2957 postType = 'videos';
2958 break;
2959 case 'link':
2960 postType = 'links';
2961 break;
2962 case 'photo':
2963 postType = 'photos';
2964 break;
2965 case 'album':
2966 postType = 'albums';
2967 break;
2968 case 'event':
2969 postType = 'events';
2970 break;
2971 }
2972 }
2973 }
2974 return postType;
2975 },
2976
2977 /**
2978 * Show or Hide Post Depending on settings
2979 *
2980 * @since 4.0
2981 *
2982 * @return bool
2983 */
2984 checkShowPost : function( post ){
2985 var self = this,
2986 feedType = self.customizerFeedData.settings.feedtype,
2987 type = self.customizerFeedData.settings.type,
2988 postType = self.getPostTypeTimeline( post ),
2989 showPost = true;
2990 //'links,events,videos,photos,albums,statuses',
2991 if(feedType == 'timeline'){
2992 showPost = type.includes( postType );
2993 }
2994 return showPost;
2995 },
2996
2997
2998 /**
2999 * Process Photos Feedtype => Single Image Source
3000 *
3001 * @since 4.0
3002 *
3003 * @return string
3004 */
3005 processPhotoSource : function( post ){
3006 var pictureSourceFallBack = 'https://graph.facebook.com/'+ post.id +'/picture?type=normal&width=9999&height=9999&access_token=' + (this.customizerFeedData.settings.sources[0] != undefined) ? this.customizerFeedData.settings.sources[0].access_token : '',
3007 pictureSrc = ( post.images && post.images[0] && post.images[0].source) ? post.images[0].source : pictureSourceFallBack;
3008 if(post.images){
3009 var currentWidth = 0;
3010 post.images.forEach( function(singleImage) {
3011 if( singleImage.width > 500 && singleImage.width < 900 && currentWidth < singleImage.width){
3012 pictureSrc = singleImage.source;
3013 currentWidth = singleImage.width;
3014 }
3015 });
3016 }
3017 return pictureSrc;
3018 },
3019
3020
3021 /**
3022 * Process Video Source Image
3023 * Videos Feed Type
3024 * @since 4.0
3025 *
3026 * @return string
3027 */
3028 processVideosFeedImage : function( videoPost ){
3029 var self = this,
3030 pictureSrc = '';
3031 if( self.hasOwnNestedProperty(videoPost, 'format') && Array.isArray(videoPost.format) ){
3032 pictureSrc = videoPost.format[videoPost.format.length - 1].picture;
3033 }
3034 return pictureSrc;
3035 },
3036
3037
3038 /**
3039 * Print Expand Text
3040 *
3041 * @since 4.0
3042 *
3043 * @return String
3044 */
3045 printExpandText : function( postID ){
3046 var self = this;
3047 return self.expandedPostText.includes(postID) ? self.translatedText.seeLessText : self.translatedText.seeMoreText;
3048 },
3049
3050 /**
3051 * Print Expand Text
3052 *
3053 * @since 4.0
3054 */
3055 expandPostText : function( postID ){
3056 var self = this;
3057 if(self.expandedPostText.includes(postID)){
3058 self.expandedPostText.splice(self.expandedPostText.indexOf(postID), 1);
3059 }else{
3060 self.expandedPostText.push(postID);
3061 }
3062 setTimeout(function(){
3063 self.generateMasonryGridHeight('update');
3064 }, 100)
3065 cffBuilder.$forceUpdate();
3066
3067 },
3068
3069 /**
3070 * Return Likebox Iframe
3071 *
3072 * @since 4.0
3073 *
3074 * @return String
3075 */
3076 displayLikeBoxIframe : function(){
3077 var self = this,
3078 pageID = self.hasOwnNestedProperty(self.customizerFeedData, 'header.id') ? self.customizerFeedData.header.id : null,
3079 settings = self.customizerFeedData.settings,
3080 likeBoxWidth = self.valueIsEnabled(settings.likeboxcustomwidth) && self.checkNotEmpty(settings.likeboxcustomwidth) ? settings.likeboxwidth : 300,
3081 iframeURL = 'https://www.facebook.com/'+pageID+'/tabs&width=' + likeBoxWidth +
3082 '&small_header=' + self.valueIsEnabled(settings.likeboxsmallheader) +
3083 '&adapt_container_width=true' +
3084 '&hide_cover=' + !self.valueIsEnabled(settings.likeboxcover) +
3085 '&hide_cta=' + self.valueIsEnabled(settings.likeboxhidebtn) +
3086 '&show_facepile=' + self.valueIsEnabled(settings.likeboxfaces) +
3087 '&locale=' + settings.locale;
3088 return 'https://www.facebook.com/plugins/page.php?href='+iframeURL;
3089 },
3090
3091 /**
3092 * Single Post & Feature Post Holder Areas
3093 *
3094 * @since 4.0
3095 */
3096 singleHolderParams : function(){
3097 var self = this,
3098 postsLength = self.customizerFeedData.posts ? self.customizerFeedData.posts.length : 0;
3099 holderIcon = '',
3100 holderHeading = '',
3101 holderText = '',
3102 settings = self.customizerFeedData.settings;
3103
3104 if( settings.feedtype == 'singlealbum' ){
3105 holderIcon = self.checkNotEmpty(settings.album) && postsLength == 0 ? self.svgIcons['issueSinglePreview'] : self.svgIcons['albumsPreview'];
3106 holderHeading = self.checkNotEmpty(settings.album) && postsLength == 0 ? self.addFeaturedAlbumScreen.couldNotFetch : self.addFeaturedAlbumScreen.previewHeading;
3107 holderText = self.checkNotEmpty(settings.album) && postsLength == 0 ? self.addFeaturedAlbumScreen.unablePreview : self.addFeaturedAlbumScreen.previewText;
3108 }
3109 if( settings.feedtype == 'featuredpost' ){
3110 holderIcon = self.checkNotEmpty(settings.featuredpost) && postsLength == 0 ? self.svgIcons['issueSinglePreview'] : self.svgIcons['featuredPostPreview'];
3111 holderHeading = self.checkNotEmpty(settings.featuredpost) && postsLength == 0 ? self.addFeaturedPostScreen.couldNotFetch : self.addFeaturedPostScreen.previewHeading;
3112 holderText = self.checkNotEmpty(settings.featuredpost) && postsLength == 0 ? self.addFeaturedPostScreen.unablePreview : self.addFeaturedPostScreen.previewText;
3113 }
3114
3115 return {
3116 icon : holderIcon,
3117 heading : holderHeading,
3118 text : holderText
3119 };
3120
3121 },
3122
3123 /**
3124 * Toggle Social Share Tooltip
3125 *
3126 * @since 4.0
3127 */
3128 toggleSocialShareTooltip : function( postID ){
3129 var self = this;
3130 self.showedSocialShareTooltip = (self.showedSocialShareTooltip === postID) ? null : postID;
3131 cffBuilder.$forceUpdate();
3132 },
3133
3134
3135 /**
3136 * Open Dialog Box
3137 *
3138 * @since 4.0
3139 */
3140 openDialogBox : function(type, args = []){
3141 var self = this,
3142 heading = self.dialogBoxPopupScreen[type].heading,
3143 description = self.dialogBoxPopupScreen[type].description;
3144 switch (type) {
3145 case "deleteSourceCustomizer":
3146 self.sourceToDelete = args;
3147 heading = heading.replace("#", self.sourceToDelete.username);
3148 break;
3149 case "deleteSingleFeed":
3150 self.feedToDelete = args;
3151 heading = heading.replace("#", self.feedToDelete.feed_name);
3152 break;
3153 case "deleteSource":
3154 self.sourceToDelete = args;
3155 heading = heading.replace("#", self.sourceToDelete.username);
3156 break;
3157
3158 }
3159 self.dialogBox = {
3160 active : true,
3161 type : type,
3162 heading : heading,
3163 description : description
3164 };
3165 },
3166
3167
3168 /**
3169 * Confirm Dialog Box Actions
3170 *
3171 * @since 4.0
3172 */
3173 confirmDialogAction : function(){
3174 var self = this;
3175 switch (self.dialogBox.type) {
3176 case 'deleteSourceCustomizer':
3177 self.selectSourceCustomizer(self.sourceToDelete, true);
3178 self.customizerControlAjaxAction('feedFlyPreview');
3179 break;
3180 case 'deleteSingleFeed':
3181 self.feedActionDelete([self.feedToDelete.id]);
3182 break;
3183 case 'deleteMultipleFeeds':
3184 self.feedActionDelete(self.feedsSelected);
3185 break;
3186 case 'backAllToFeed':
3187 window.location = self.builderUrl;
3188 break;
3189 case 'deleteSource':
3190 self.deleteSource(self.sourceToDelete);
3191 break;
3192 }
3193 },
3194
3195 /*
3196 closeConfirmDialog : function(){
3197 this.sourceToDelete = {};
3198 this.feedToDelete = {};
3199 this.dialogBox = {
3200 active : false,
3201 type : null,
3202 heading : null,
3203 description : null
3204 };
3205 },
3206 */
3207
3208 /**
3209 * Show Tooltip on Hover
3210 *
3211 * @since 4.0
3212 */
3213 toggleElementTooltip : function(tooltipText, type, align = 'center'){
3214 var self = this,
3215 target = window.event.currentTarget,
3216 tooltip = (target != undefined && target != null) ? document.querySelector('.sb-control-elem-tltp-content') : null;
3217 if(tooltip != null && type == 'show'){
3218 self.tooltip.text = tooltipText;
3219 var position = target.getBoundingClientRect(),
3220 left = position.left + 7,
3221 top = position.top - 15;
3222 tooltip.style.left = left + 'px';
3223 tooltip.style.top = top + 'px';
3224 tooltip.style.textAlign = align;
3225 self.tooltip.hover = true;
3226 }
3227 if(type == 'hide'){
3228 setTimeout(function(){
3229 if(self.tooltip.hoverType != 'inside'){
3230 self.tooltip.hover = false;
3231 }
3232 }, 200)
3233 }
3234 },
3235
3236 /**
3237 * Hover Tooltip
3238 *
3239 * @since 4.0
3240 */
3241 hoverTooltip : function(type, hoverType){
3242 this.tooltip.hover = type;
3243 this.tooltip.hoverType = hoverType;
3244 },
3245
3246 /**
3247 * Loading Bar & Notification
3248 *
3249 * @since 4.0
3250 */
3251 processNotification : function( notificationType ){
3252 var self = this,
3253 notification = self.genericText.notification[ notificationType ];
3254 self.loadingBar = false;
3255 self.notificationElement = {
3256 type : notification.type,
3257 text : notification.text,
3258 shown : "shown"
3259 };
3260 setTimeout(function(){
3261 self.notificationElement.shown = "hidden";
3262 }, 5000);
3263 },
3264
3265 ctaToggleFeatures: function() {
3266 this.freeCtaShowFeatures = !this.freeCtaShowFeatures;
3267 },
3268
3269 /**
3270 * Next Wizard Step
3271 *
3272 * @since 6.3
3273 */
3274 nextWizardStep : function( action = false ){
3275 const self = this;
3276 if( action === 'submit' ){
3277 self.submitWizardData()
3278 }
3279
3280 if( self.currentOnboardingWizardStep < self.onboardingWizardContent.steps.length ){
3281 self.currentOnboardingWizardStep +=1;
3282 self.recordUsageEvent( 'setup_wizard_step_completed' );
3283 self.announceWizardStep();
3284 self.$nextTick(function () {
3285 const heading = document.querySelector('.sb-onboarding-wizard-step-ctn:not([style*="display: none"]) .sb-onboarding-wizard-step-heading, .sb-onboarding-wizard-step-ctn:not([style*="display: none"]) h3, .sb-onboarding-wizard-step-ctn:not([style*="display: none"]) h4');
3286 if (heading) { heading.focus(); }
3287 });
3288 }
3289 },
3290
3291 //
3292 submitWizardData : function(){
3293 const self = this,
3294 wizardData = {
3295 action: 'cff_feed_saver_manager_process_wizard',
3296 data: JSON.stringify(self.currentOnboardingWizardActiveSettings)
3297 };
3298
3299 self.ajaxPost(wizardData, function (_ref) {
3300 });
3301
3302 if( self.sourcesList.length > 0 ){
3303 self.onboardingSuccessMessagesDisplay.push( self.onboardingSuccessMessages.connectAccount );
3304 }
3305 self.onboardingSuccessMessagesDisplay.push( self.onboardingSuccessMessages.setupFeatures );
3306
3307 const settingsValues = Object.values(self.currentOnboardingWizardActiveSettings),
3308 settingsKeys = Object.keys(self.currentOnboardingWizardActiveSettings);
3309 settingsValues.map( ( st, stInd ) => {
3310 if( st?.plugins && st?.plugins === 'smash' ){
3311 self.onboardingSuccessMessagesDisplay.push( self.onboardingSuccessMessages.feedPlugins.replace('#', settingsKeys[stInd]) );
3312 }else if( st?.id === 'reviews' ){
3313 self.onboardingSuccessMessagesDisplay.push( 'Reviews ' + self.genericText.installed );
3314 }else if( st?.id === 'wpchat' ){
3315 self.onboardingSuccessMessagesDisplay.push( 'WPChat ' + self.genericText.installed );
3316 }else if( st?.type === 'install_plugins' ){
3317 self.onboardingSuccessMessagesDisplay.push( '<span class="sb-onboarding-wizard-succes-name"> ' + st?.pluginName + '</span> ' + self.genericText.installed );
3318 }
3319 } )
3320 setTimeout(function(){
3321 self.onboardingWizardDone = 'true';
3322 self.recordUsageEvent( 'setup_wizard_completed' );
3323 }, 100)
3324 cffBuilder.$forceUpdate();
3325 },
3326
3327 /**
3328 * Previous Wizard Step
3329 *
3330 * @since 6.3
3331 */
3332 previousWizardStep : function(){
3333 const self = this;
3334 if( self.currentOnboardingWizardStep > 0 ){
3335 self.currentOnboardingWizardStep -=1;
3336 self.announceWizardStep();
3337 self.$nextTick(function () {
3338 const heading = document.querySelector('.sb-onboarding-wizard-step-ctn:not([style*="display: none"]) .sb-onboarding-wizard-step-heading, .sb-onboarding-wizard-step-ctn:not([style*="display: none"]) h3, .sb-onboarding-wizard-step-ctn:not([style*="display: none"]) h4');
3339 if (heading) { heading.focus(); }
3340 });
3341 }
3342 },
3343
3344 /**
3345 * Update the sr-only wizard step announcement ("Step N of M: Label").
3346 * Ported from instagram-feed (announceWizardStep).
3347 *
3348 * @since 4.0
3349 */
3350 announceWizardStep : function(){
3351 const self = this;
3352 const steps = self.onboardingWizardContent && self.onboardingWizardContent.steps ? self.onboardingWizardContent.steps : [];
3353 const total = Math.max(steps.length - 1, 0);
3354 const current = self.currentOnboardingWizardStep;
3355 if (current < 1 || total < 1) {
3356 self.stepAnnouncement = '';
3357 return;
3358 }
3359 const step = steps[current] || {};
3360 const label = step.label || step.title || step.heading || '';
3361 const stepWord = (self.genericText && self.genericText.wizardStep) ? self.genericText.wizardStep : 'Step';
3362 const ofWord = (self.genericText && self.genericText.wizardStepOf) ? self.genericText.wizardStepOf : 'of';
3363 self.stepAnnouncement = stepWord + ' ' + current + ' ' + ofWord + ' ' + total + (label ? ': ' + label : '');
3364 },
3365
3366 /**
3367 * Delete Source Ajax
3368 *
3369 * @since 4.0
3370 */
3371 deleteSource: function (sourceToDelete) {
3372 var self = this,
3373 deleteSourceData = {
3374 action: 'cff_feed_saver_manager_delete_source',
3375 source_id: sourceToDelete.id,
3376 username : sourceToDelete.username,
3377 nonce : self.admin_nonce
3378 };
3379 self.ajaxPost(deleteSourceData, function (_ref) {
3380 var data = _ref.data;
3381 self.sourcesList = data;
3382 });
3383 },
3384
3385 //Get Source Avatarr
3386 getSourceListAvatar: function ( source ) {
3387 return typeof source.avatar_url !== 'undefined' && source.account_type === 'group' ? source.avatar_url : 'https://graph.facebook.com/'+source.account_id+'/picture'
3388 },
3389
3390 //Switcher Onboarding Wizard Click
3391 switcherOnboardingWizardClick : function ( elem ) {
3392 const self = this;
3393 if( elem?.uncheck === true ){
3394 return false;
3395 }
3396
3397 if(self.currentOnboardingWizardActiveSettings[elem?.data?.id] !== undefined){
3398 delete self.currentOnboardingWizardActiveSettings[elem.data.id];
3399 }else{
3400 self.currentOnboardingWizardActiveSettings[elem.data.id] = elem.data;
3401 }
3402 cffBuilder.$forceUpdate();
3403 },
3404
3405 //Select Option Wizard change
3406 selectOptionOnboardingWizardChange : function ( elem ) {
3407 const self = this,
3408 elemValue = event.target.value,
3409 elemData = {
3410 ...elem.data,
3411 value : elemValue
3412 };
3413 self.currentOnboardingWizardActiveSettings[elem.data.id] = elemData;
3414 console.log(elemData);
3415 cffBuilder.$forceUpdate();
3416 },
3417
3418 switcherOnboardingWizardCheckActive : function ( elem ) {
3419 const self = this;
3420 if( elem?.uncheck === true ){
3421 return elem?.active;
3422 }else{
3423 return self.currentOnboardingWizardActiveSettings[elem?.data?.id] !== undefined ? 'true' : 'false'
3424 }
3425
3426 },
3427
3428 checkActiveOnboardingWizardSettings : function (){
3429 const self = this,
3430 currentStepContentSteps = self.onboardingWizardContent.steps;
3431
3432 currentStepContentSteps.map( (step, stepId) => {
3433 let = currentStepContentValues = Object.values(step),
3434 currentStepContentKeys = Object.keys(step);
3435 currentStepContentValues.map( (sec, secId) => {
3436 if( (self.onboardingWizardContent.saveSettings.includes(currentStepContentKeys[secId])) ){
3437 currentStepContentValues[secId].forEach( elem => {
3438 if( elem.active === true && elem?.data){
3439 self.currentOnboardingWizardActiveSettings[elem.data.id] = elem.data;
3440 }
3441 } );
3442 }
3443 });
3444 });
3445 },
3446
3447 recordUsageEvent : function( eventName ) {
3448 if ( typeof window.cffSmashUsageRecordEvent === 'function' ) {
3449 window.cffSmashUsageRecordEvent( eventName );
3450 }
3451 },
3452
3453 dismissOnboardingWizard : function(){
3454 this.recordUsageEvent( 'setup_wizard_abandoned' );
3455 const self = this,
3456 dismissWizardData = {
3457 action: 'cff_feed_saver_manager_dismiss_wizard'
3458 };
3459
3460 self.ajaxPost(dismissWizardData, function (_ref) {
3461 window.location = self.builderUrl;
3462 });
3463 cffBuilder.$forceUpdate();
3464 },
3465 //One CLick Upgrade
3466 runOneClickUpgrade : function(){
3467 const self = this,
3468 oneClickUpgradeData = {
3469 action: 'cff_maybe_upgrade_redirect',
3470 license_key: self.setupLicencekey,
3471 nonce : self.admin_nonce
3472 };
3473 self.setupLicencekeyError = null
3474 if( self.checkNotEmpty( self.setupLicencekey ) ){
3475 self.licenseLoading = true;
3476 self.ajaxPost(oneClickUpgradeData, function (_ref) {
3477 var data = _ref.data;
3478 if (data.success === false) {
3479 self.licenseLoading = false;
3480 if (typeof data.data !== 'undefined') {
3481 self.setupLicencekeyError = data.data.message
3482 }
3483 }
3484 if (data.success === true) {
3485 window.location.href = data.data.url
3486 }
3487
3488 });
3489 }
3490
3491 },
3492
3493 //Source Ative
3494 isSourceSelectActive : function(source){
3495 if(this.selectedSources.includes(source.account_id)){
3496 return (this.selectedFeed == 'events' && (source.privilege == 'events' || source.account_type == 'group')) || (this.selectedFeed != 'events' && source.privilege != 'events');
3497 }
3498 return false;
3499 },
3500
3501 //Source Ative
3502 isSourceSelectActivePopup : function(source){
3503 if(this.selectedSources.includes(source.account_id)){
3504 return (this.customizerFeedData.settings.feedtype == 'events' && source.privilege == 'events') || (this.customizerFeedData.settings.feedtype != 'events' && source.privilege != 'events');
3505 }
3506 return false;
3507 },
3508 checkTypeForGroupPopup : function(source){
3509 return source.account_type === 'group' && this.customizerFeedData.settings.feedtype === 'photos';
3510 },
3511
3512 }
3513
3514 });
3515
3516
3517