1// var url = new URL(location.href) 2// var search = url.search; 3 4function showSubscriptionPopup(videoPlayer) { 5 console.log('showSubscriptionPopup'); 6 videoPlayer.parentElement.classList.add('join-popup-added') 7 let markup = ` 8 <section class="join-popup--block"> 9 <div style="join-popup--content"> 10 <h2>Want more?</h2> 11 <p>Upgrade to continue watching</p> 12 <a target="_top" href="https://unifyd.tv/join_us"> 13 Start for Free 14 </a> 15 </div> 16 </section> 17 `; 18 videoPlayer.insertAdjacentHTML('afterEnd', markup) 19} 20 21let detetTemplates = () => { 22 23 let catalogLink = document.querySelector('.header a[href="/catalog"]:not(.touched)'); 24 if (catalogLink) { 25 catalogLink.classList.add('touched') 26 console.log(catalogLink); 27 catalogLink.addEventListener('click', function() { 28 e.preventDefault(); 29 location.replace('/catalog') 30 }) 31 } 32 33 if (location.href.includes('/categories/')) { 34 let wrapper = document.querySelector('#category_content:not(.category-embeded)'); 35 if (wrapper) { 36 wrapper.classList.add('category-embeded') 37 if (!document.querySelector('#subcategories_script')) { 38 wrapper.insertAdjacentHTML('afterEnd', ` 39 <turbo-frame id="subcategories_script" src="/pages/subcategories"></turbo-frame> 40 `) 41 } 42 } 43 } 44 45 if (location.href.includes('/programs')) { 46 let videoPlayer = document.querySelector('video:not(.touched)'); 47 48 if (videoPlayer) { 49 videoPlayer.classList.add('touched'); 50 51 let getPermalinkFromURL = (url) => { 52 return url.substring(url.indexOf('/programs/') + 10).split('?')[0]; 53 }; 54 55 let programUrl = getPermalinkFromURL(location.href); 56 console.log(programUrl) 57 58 axios.get(`/api/contents/${programUrl}`).then(function (response) { 59 let program = response.data; 60 console.log(program); 61 62 let recommendVideos = []; 63 let freeToWatch = false; 64 65 if (program.tags.length) { 66 program.tags.forEach(tag => { 67 if (tag.split('|')[0].trim().toLowerCase() === 'recommend') { 68 recommendVideos.push(tag.split('|')[1].trim()); 69 } 70 }); 71 72 program.tags.forEach(tag => { 73 if (tag.split('|')[0].trim().toLowerCase() === 'free-to-watch') { 74 freeToWatch = tag.split('|')[1].trim(); 75 } 76 }); 77 } 78 79 axios.get(`/api/sessions`).then(function (response) { 80 let session = response.data; 81 if (session.logged) { 82 83 axios.get(`/api/users/me`).then(function (response) { 84 let user = response.data; 85 86 if (!user.subscriber) { 87 console.log('user not subscriber!!!!') 88 if (freeToWatch && videoPlayer) { 89 console.log('freeToWatch!'); 90 console.log(videoPlayer); 91 92 let triggered = false; // Flag to prevent multiple executions 93 94 videoPlayer.addEventListener('timeupdate', function () { 95 if (videoPlayer.currentTime >= freeToWatch) { 96 97 98 videoPlayer.pause(); // Stop the video 99 // videoPlayer.currentTime = freeToWatch; // Prevent seeking past limit 100 101 102 if (!triggered) { 103 triggered = true; 104 videoPlayer.controls = false; 105 document.querySelector('video-controls').style.display = 'none'; 106 107 showSubscriptionPopup(videoPlayer) 108 } 109 110 111 112 } 113 }); 114 } 115 } 116 }) 117 118 } else { 119 if (freeToWatch && videoPlayer) { 120 console.log('freeToWatch!'); 121 console.log(videoPlayer); 122 123 let triggered = false; // Flag to prevent multiple executions 124 125 videoPlayer.addEventListener('timeupdate', function () { 126 if (videoPlayer.currentTime >= freeToWatch) { 127 128 129 videoPlayer.pause(); // Stop the video 130 // videoPlayer.currentTime = freeToWatch; // Prevent seeking past limit 131 132 133 if (!triggered) { 134 triggered = true; 135 videoPlayer.controls = false; 136 document.querySelector('video-controls').style.display = 'none'; 137 138 showSubscriptionPopup(videoPlayer) 139 } 140 141 142 143 } 144 }); 145 } 146 } 147 }) 148 149 150 151 152 153 154 155 156 if (recommendVideos.length) { 157 console.log(recommendVideos); 158 159 let recommendedVideosMarkup = ''; 160 let fetchPromises = []; 161 162 recommendVideos.slice(0, 3).forEach(url => { 163 try { 164 let videoURL = new URL(url); 165 let videoPermalink = videoURL.pathname.split('/programs/')[1]; 166 console.log(videoPermalink); 167 168 let request = axios.get(`/api/contents/${videoPermalink}`) 169 .then(function (response) { 170 let video = response.data; 171 recommendedVideosMarkup += ` 172 <a href="${video.url}" class="recommended-video--block" target="_top"> 173 <div class="video-thumbnail" style="background-image: url('${video.main_poster}')"></div> 174 <p>${video.title}</p> 175 </a> 176 `; 177 }) 178 .catch(function (error) { 179 console.warn(`Failed to load video for ${videoPermalink}:`, error.message);
180 // Do nothing, don't add to markup 181 }); 182 183 fetchPromises.push(request); 184 } catch (e) { 185 console.warn(`Invalid video URL: ${url}`, e.message); 186 } 187 }); 188 189 Promise.all(fetchPromises).then(() => { 190 let recommendVideosSection = document.querySelector('#program_related'); 191 if (recommendVideosSection) { 192 recommendVideosSection.insertAdjacentHTML('afterEnd', ` 193 <div class="custom-recomend-section"> 194 <h3>Recommended Videos</h3> 195 <div class="custom-recomend-section--container"> 196 ${recommendedVideosMarkup} 197 </div> 198 </div> 199 `); 200 } 201 202 console.log('program.content_type', program.content_type); 203 if (program.content_type !== 'collection') { 204 videoPlayer.addEventListener('ended', function () { 205 let popup = document.createElement('div'); 206 popup.classList.add('recommendation-popup'); 207 popup.innerHTML = ` 208 <div class="popup-content"> 209 <h3>Recommended Videos</h3> 210 <div class="recommended-videos-container"> 211 ${recommendedVideosMarkup} 212 </div> 213 <button class="close-popup">Close</button> 214 </div> 215 `; 216 217 document.body.appendChild(popup); 218 219 // Close popup functionality 220 popup.querySelector('.close-popup').addEventListener('click', () => { 221 popup.remove(); 222 }); 223 224 // Optional: Close popup when clicking outside the content 225 popup.addEventListener('click', (e) => { 226 if (e.target === popup) { 227 popup.remove(); 228 } 229 }); 230 231 // Style the popup (optional, can be moved to a CSS file) 232 const styles = document.createElement('style'); 233 styles.innerHTML = ` 234 .recommendation-popup { 235 position: fixed; 236 top: 0; 237 left: 0; 238 width: 100%; 239 height: 100%; 240 background: rgba(0, 0, 0, 0.8); 241 display: flex; 242 justify-content: center; 243 align-items: center; 244 z-index: 9999; 245 } 246 .popup-content h3 { 247 font-size: 1.5rem; 248 margin-bottom: .5rem; 249 font-weight: 600; 250 } 251 .popup-content { 252 background: #000; 253 color: #fff; 254 padding: 20px; 255 border-radius: 10px; 256 text-align: center; 257 max-width: 1200px; 258 width: 90%; 259 } 260 .recommended-videos-container { 261 display: flex; 262 gap: 10px; 263 flex-wrap: wrap; 264 justify-content: center; 265 } 266 .recommended-video--block { 267 display: block; 268 text-decoration: none; 269 color: #fff; 270 text-align: center; 271 width: 30%; 272 min-width: 250px; 273 margin-bottom: 1rem; 274 } 275 .video-thumbnail { 276 width: 100%; 277 padding-top: 56.25%; 278 background-size: cover; 279 background-position: center; 280 border-radius: 5px; 281 margin-bottom: 10px; 282 } 283 .close-popup { 284 background: var(--primary); 285 color: #fff; 286 border: none; 287 padding: 10px 20px; 288 border-radius: 5px; 289 cursor: pointer; 290 } 291 `; 292 document.head.appendChild(styles); 293 }); 294 } else { 295 // collection recommned popup 296 let currentVideoID = document.querySelector('video-player').dataset.id; 297 let lastChapterID = program.children_videos.at(-1).id; 298 299 console.log('lastChapterID', lastChapterID) 300 console.log('currentVideoID', currentVideoID) 301 302 if (currentVideoID == lastChapterID) { 303 videoPlayer.addEventListener('ended', function () { 304 let popup = document.createElement('div'); 305 popup.classList.add('recommendation-popup'); 306 popup.innerHTML = ` 307 <div class="popup-content"> 308 <h3>Recommended Videos</h3> 309 <div class="recommended-videos-container"> 310 ${recommendedVideosMarkup} 311 </div> 312 <button class="close-popup">Close</button> 313 </div> 314 `; 315
316 document.body.appendChild(popup); 317 318 // Close popup functionality 319 popup.querySelector('.close-popup').addEventListener('click', () => { 320 popup.remove(); 321 }); 322 323 // Optional: Close popup when clicking outside the content 324 popup.addEventListener('click', (e) => { 325 if (e.target === popup) { 326 popup.remove(); 327 } 328 }); 329 330 // Style the popup (optional, can be moved to a CSS file) 331 const styles = document.createElement('style'); 332 styles.innerHTML = ` 333 .recommendation-popup { 334 position: fixed; 335 top: 0; 336 left: 0; 337 width: 100%; 338 height: 100%; 339 background: rgba(0, 0, 0, 0.8); 340 display: flex; 341 justify-content: center; 342 align-items: center; 343 z-index: 9999; 344 } 345 .popup-content h3 { 346 font-size: 1.5rem; 347 margin-bottom: .5rem; 348 font-weight: 600; 349 } 350 .popup-content { 351 background: #000; 352 color: #fff; 353 padding: 20px; 354 border-radius: 10px; 355 text-align: center; 356 max-width: 1200px; 357 width: 90%; 358 } 359 .recommended-videos-container { 360 display: flex; 361 gap: 10px; 362 flex-wrap: wrap; 363 justify-content: center; 364 } 365 .recommended-video--block { 366 display: block; 367 text-decoration: none; 368 color: #fff; 369 text-align: center; 370 width: 30%; 371 min-width: 250px; 372 margin-bottom: 1rem; 373 } 374 .video-thumbnail { 375 width: 100%; 376 padding-top: 56.25%; 377 background-size: cover; 378 background-position: center; 379 border-radius: 5px; 380 margin-bottom: 10px; 381 } 382 .close-popup { 383 background: var(--primary); 384 color: #fff; 385 border: none; 386 padding: 10px 20px; 387 border-radius: 5px; 388 cursor: pointer; 389 } 390 `; 391 document.head.appendChild(styles); 392 }); 393 } 394 395 396 397 398 } 399 400 401 402 }); 403 } 404 405 406 }); 407 } 408 } 409 410 let thetimeisnowPopup = document.querySelector('.thetimeisnow-popup #leadzen_card > div:not(.touched)'); 411 if (thetimeisnowPopup) { 412 thetimeisnowPopup.classList.add('touched') 413 414 let title = thetimeisnowPopup.querySelector('h3'); 415 if (title) {
416 if (title.innerText.trim() === 'Create an account to get your special offer!') { 417 title.innerText = 'Enter your contact information to instantly watch for free!' 418 } 419 } 420 421 422 let submitButton = thetimeisnowPopup.querySelector('#submit-button'); 423 if (submitButton) { 424 let text = submitButton.querySelector('span'); 425 if (text) { 426 if (text.innerText.trim() === 'Continue') { 427 text.innerText = 'WATCH NOW' 428 } 429 } 430 } 431 432 } 433 434 if (location.href.includes('/join_us')) { 435 436 let planMontly = document.querySelector('#plan-205974-block:not(.touched)'); 437 if (planMontly) { 438 planMontly.classList.add('touched', 'relative'); 439 440 let priceText = planMontly.querySelector('.flex.flex-col.items-end > span + span').innerText; 441 planMontly.querySelector('.flex.flex-col.items-end > span:nth-of-type(1)').innerText = priceText; 442 planMontly.querySelector('.flex.flex-col.items-end > span + span').innerText = ''; 443 } 444 445 446 let planMontlyPlus = document.querySelector('#plan-211012-block:not(.touched)'); 447 if (planMontlyPlus) { 448 planMontlyPlus.classList.add('touched', 'relative'); 449 planMontlyPlus.insertAdjacentHTML('afterBegin', ` 450 <span class="top-label-plan">MOST POPULAR</span> 451 `) 452 453 let priceText = planMontlyPlus.querySelector('.flex.flex-col.items-end > span + span').innerText; 454 planMontlyPlus.querySelector('.flex.flex-col.items-end > span:nth-of-type(1)').innerHTML = priceText; 455 planMontlyPlus.querySelector('.flex.flex-col.items-end > span + span').innerText = ''; 456 } 457 458 let planYearlyPlus = document.querySelector('#plan-211012-block:not(.touched)'); 459 if (planYearlyPlus) { 460 planYearlyPlus.classList.add('touched', 'relative'); 461 // planYearlyPlus.insertAdjacentHTML('afterBegin', ` 462 // <span class="top-label-plan">BEST VALUE</span> 463 // `) 464 465 let priceText = planYearlyPlus.querySelector('.flex.flex-col.items-end > span + span').innerText; 466 planYearlyPlus.querySelector('.flex.flex-col.items-end > span + span').classList.add('text-right') 467 planYearlyPlus.querySelector('.flex.flex-col.items-end > span:nth-of-type(1)').innerHTML = ` 468 <span class="stroke-text">USD 179.88/year</span> 469 <span style="color: #d63b32 !important;">${priceText}</span> 470 `; 471 472 473 planYearlyPlus.querySelector('.flex.flex-col.items-end > span + span').innerText = ''; 474 } 475 476 477 478 let wrapper = document.querySelector('[data-test="branding"] + p:not(.touched)'); 479 if (wrapper) { 480 wrapper.classList.add('touched'); 481 let markup = ` 482 <div class="already-have-an-account"> 483 Already have an account? <a href="/sign_in">Sign in here</a> 484 </div> 485 ` 486 wrapper.insertAdjacentHTML('afterEnd', markup); 487 } 488 } 489 490 if (location.href.includes('success')) { 491 492 if (location.href.includes('&o=110384&p=110384')) { 493 494 let wrapper = document.querySelector('body:not(.redirected-success)') 495 if (wrapper) { 496 wrapper.classList.add('redirected-success') 497 console.log('&o=110384&p=110384') 498 location.replace('/pages/plans') 499 } 500 } 501 } 502 503 // url = new URL(location.href) 504 505 // if (url.pathname === '/catalog/search') { 506 // let content = document.querySelector('#catalog_content') 507 // if (content) { 508 // if (search !== url.search) { 509 // search = url.search; 510 // setTimeout(()=>{ 511 // let y = document.querySelector('#catalog_content').getBoundingClientRect().top + window.scrollY; 512 // window.scroll({ 513 // top: y, 514 // behavior: 'smooth' 515 // }) 516 // console.log("search != url.search") 517 // }, 500) 518 // } else { 519 // // console.log("search == url.search") 520 // } 521 // } 522 // } 523 524 if (location.href.includes('/checkout/new?o=110384')) { 525 let registrerButton = document.querySelector('#submit-button .text-lg:not(.touched)') 526 if (registrerButton) { 527 registrerButton.classList.add('touched') 528 if (registrerButton.innerText.trim() === 'Claim my free bundle!') { 529 registrerButton.innerText = 'Register' 530 } 531 } 532 533 } 534 535 let getAccessDropdown = document.querySelector('ds-dropdown[data-test="subscriptions-list"]:not(.touched)') 536 if (getAccessDropdown) { 537 getAccessDropdown.classList.add('touched') 538 let markup = `<a href="/join_us" data-turbo-frame="_top" class="custom-get-access">Watch with Free Trial</a>`; 539 if (USER_GUEST) { 540 markup = `<a href="/join_us" data-turbo-frame="_top" class="custom-get-access">Watch with Free Trial</a>`; 541 } 542 getAccessDropdown.insertAdjacentHTML('beforeBegin', markup) 543 } 544 545 let getAcessNowButton = document.querySelector('a[data-analytics-event-name-param="clicked_get_access_button"]:not(.touhed)'); 546 if (getAcessNowButton) { 547 if (USER_GUEST) { 548 getAcessNowButton.href = '/join' 549 } else { 550 getAcessNowButton.href = '/join' 551 } 552 553 getAcessNowButton.classList.add('touched'); 554 } 555 556 if (location.href.includes('/catalog')) {
557 let catalogWrapper = document.querySelector('.catalog-area:not(.embeded-touched)'); 558 if (catalogWrapper) { 559 catalogWrapper.classList.add('embeded-touched') 560 catalogWrapper.insertAdjacentHTML('afterBegin', ` 561 <div class="catalog-embeded-content"> 562 <turbo-frame id="custom_catalog" src="/pages/subscribers-catalog"></turbo-frame> 563 </div> 564 `) 565 566 catalogWrapper.insertAdjacentHTML('beforeEnd', ` 567 <div class="catalog-embeded-content"> 568 <turbo-frame id="custom_catalog_bottom" src="/pages/subscribers-catalog-bottom"></turbo-frame> 569 </div> 570 `) 571 572 } 573 } 574 575 if (location.href.includes('/sign_in') || location.href.includes('/forgot_password') || location.href.includes('/reset_password')) { 576 let layout = document.querySelector('.layout:not(.touched)'); 577 if (layout) { 578 layout.classList.add('touched'); 579 layout.classList.add('common-registration-layout'); 580 layout.classList.add('common-sign-in-layout'); 581 } 582 } 583 584 if (location.href.includes('/checkout/new?o=')) { 585 let emailInput = document.querySelector('input[name="form[email]"]:not(.touched-label)') 586 if (emailInput) { 587 emailInput.classList.add('touched-label') 588 emailInput.parentElement.parentElement.querySelector('p').innerHTML = 'Email <span style="color: #5ad1f7">(Username)</span>' 589 } 590 } 591 592 // old id 102152 593 if (location.href.includes('/checkout/new?o=') && !location.href.includes('?o=110384') ) { 594 let userEmail = localStorage.getItem('registration_email'); 595 if (userEmail) { 596 let emailInput = document.querySelector('input[name="form[email]"]:not(.touched)') 597 if (emailInput) { 598 emailInput.value = userEmail; 599 emailInput.classList.add('touched') 600 } 601 } 602 603 let layout = document.querySelector('body > .min-h-screen:not(.touched)'); 604 if (layout) { 605 layout.classList.add('touched'); 606 607 608 layout.insertAdjacentHTML('beforeBegin', '<link rel="stylesheet" type="text/css" href="/assets/theme.css"> <link rel="stylesheet" type="text/css" href="/assets/custom_styles.css">') 609 610 611 axios.get('/pages/registration').then(response => { 612 let parser = new DOMParser(); 613 let htmlDoc = parser.parseFromString(response.data, 'text/html'); 614 615 let headerMarkup = htmlDoc.querySelector('div[data-block-type="registration_header"]').innerHTML 616 if (!document.querySelector('div[data-block-type="registration_header"]')) layout.insertAdjacentHTML('beforeBegin', headerMarkup) 617 618 let footerMarkup = htmlDoc.querySelector('.footer-wrapper').innerHTML 619 if (!document.querySelector('.footer-wrapper')) layout.insertAdjacentHTML('afterEnd', footerMarkup) 620 621 layout.classList.add('common-registration-layout'); 622 }) 623 } 624 625 } 626 627 if (location.href.includes('/checkout/new?o=110384')) { 628 629 let userEmail = localStorage.getItem('registration_email'); 630 if (userEmail) { 631 let emailInput = document.querySelector('input[name="form[email]"]:not(.touched)') 632 if (emailInput) { 633 emailInput.value = userEmail; 634 emailInput.classList.add('touched') 635 } 636 } 637 638 let registrationForm = document.querySelector('#registration_form') 639 if (!registrationForm) { 640 let wrapper = document.querySelector('body > .min-h-screen:not(.redirected)') 641 if (wrapper) { 642 localStorage.setItem('registration_email', ''); 643 location.replace('/pages/select-your-plan') 644 wrapper.classList.add('redirected') 645 } 646 } 647 648 // document.querySelectorAll('.checkbox .label:not(.touched)').forEach(label => { 649 // label.classList.add('touched') 650 // if (label.innerText.trim() === 'By clicking this box you agree to the Terms & Conditions') { 651 // label.innerHTML = ` 652 // I agree to the <a target="_blank" href="/pages/terms-of-use">Terms of Use</a> and <a href="/pages/privacy" target="_blank">Privacy Policy</a> by checking this box. Select to create an account. 653 // ` 654 // } 655 // if (label.innerText.trim() === 'Occasionally receive marketing news and updates') { 656 // label.innerHTML = ` 657 // I would like to receive UNIFYD emails with the latest news about new shows, movies and live events. You can unsubscribe at any time. 658 // ` 659 // } 660 // }) 661 662 let titleArea = document.querySelector('#registration_form > div > div:not(.touched)') 663 if (titleArea) { 664 titleArea.classList.add('touched') 665 666 let markup = ` 667 <h2 class="registration-top-title">STEP 1 OF 3</h2> 668 <h1 class="registration-title">Create a password to start <br> your free trial</h1> 669 <h3 class="registration-bottom-title">Almost Done! Access to our full catalog <br> is just a few more clicks away.</h3> 670 ` 671 titleArea.insertAdjacentHTML('afterEnd', markup) 672 } 673 674 let layout = document.querySelector('body > .min-h-screen:not(.touched)'); 675 if (layout) { 676 layout.classList.add('touched'); 677 678 679 layout.insertAdjacentHTML('beforeBegin', '<link rel="stylesheet" type="text/css" href="/assets/theme.css"> <link rel="stylesheet" type="text/css" href="/assets/custom_styles.css">') 680 681 682 axios.get('/pages/registration').then(response => { 683 let parser = new DOMParser(); 684 let htmlDoc = parser.parseFromString(response.data, 'text/html'); 685 686 let headerMarkup = htmlDoc.querySelector('div[data-block-type="registration_header"]').innerHTML 687 if (!document.querySelector('div[data-block-type="registration_header"]')) layout.insertAdjacentHTML('beforeBegin', headerMarkup) 688 689 let footerMarkup = htmlDoc.querySelector('.footer-wrapper').innerHTML 690 if (!document.querySelector('.footer-wrapper')) layout.insertAdjacentHTML('afterEnd', footerMarkup) 691 692 layout.classList.add('registration-layout'); 693 }) 694 } 695 } 696 697 if (location.href.includes('/orders/checkout?')) { 698 let layout = document.querySelector('body > .relative .layout:not(.touched)'); 699 if (layout) { 700 layout.classList.add('touched'); 701 702 703 layout.insertAdjacentHTML('beforeBegin', '<link rel="stylesheet" type="text/css" href="/assets/theme.css"> <link rel="stylesheet" type="text/css" href="/assets/custom_styles.css">') 704 705 706 axios.get('/pages/registration').then(response => { 707 let parser = new DOMParser(); 708 let htmlDoc = parser.parseFromString(response.data, 'text/html'); 709 710 let headerMarkup = htmlDoc.querySelector('div[data-block-type="registration_header"]').innerHTML 711 if (!document.querySelector('div[data-block-type="registration_header"]')) layout.insertAdjacentHTML('beforeBegin', headerMarkup) 712 713 let footerMarkup = htmlDoc.querySelector('.footer-wrapper').innerHTML 714 if (!document.querySelector('.footer-wrapper')) layout.insertAdjacentHTML('afterEnd', footerMarkup) 715 716 layout.classList.add('registration-layout'); 717 }) 718 } 719 } 720 setTimeout(() => detetTemplates(), 500) 721} 722detetTemplates()
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.