templates/ProfileList/_favorite-button.partial.script.js line 1

Open in your IDE?
  1. customElements.define('favorite-button', class extends HTMLElement {
  2.     static observedAttributes = ['text', 'liked'];
  3.     constructor () {
  4.         super();
  5.         this.apiCheck = this.getAttribute('api-check');
  6.         if (!this.apiCheck) return;
  7.         this.apiLike = this.getAttribute('api-like');
  8.         this.apiUnlike = this.getAttribute('api-unlike');
  9.         this.isLiked = false;
  10.         this.tippyData = {
  11.             'false': 'Добавить в избранное',
  12.             'true': 'Удалить из избранного' 
  13.         }
  14.         this.alternativeDesign = this.hasAttribute('alternative');
  15.         this.alternativeSvg = {
  16.             like: '<path d="m20 35.58-2.42-2.16c-2.8-2.53-5.12-4.71-6.95-6.55a46.04 46.04 0 0 1-4.38-4.93 15.65 15.65 0 0 1-2.27-4.02 11.25 11.25 0 0 1-.65-3.75c0-2.61.88-4.8 2.63-6.54A8.88 8.88 0 0 1 12.5 5 9.88 9.88 0 0 1 20 8.5 9.88 9.88 0 0 1 27.5 5c2.61 0 4.8.88 6.54 2.63a8.88 8.88 0 0 1 2.63 6.54c0 1.27-.22 2.52-.65 3.75a15.63 15.63 0 0 1-2.27 4.02 46.03 46.03 0 0 1-4.38 4.93 188.43 188.43 0 0 1-6.95 6.55L20 35.58Z"/>',
  17.             unlike: '<path d="m20 35.58-2.42-2.16a188.5 188.5 0 0 1-6.95-6.55 46.04 46.04 0 0 1-4.38-4.93 15.65 15.65 0 0 1-2.27-4.02 11.25 11.25 0 0 1-.65-3.75c0-2.61.88-4.8 2.63-6.54A8.88 8.88 0 0 1 12.5 5 9.88 9.88 0 0 1 20 8.5 9.88 9.88 0 0 1 27.5 5c2.61 0 4.8.88 6.54 2.63a8.88 8.88 0 0 1 2.63 6.54c0 1.27-.22 2.52-.65 3.75a15.63 15.63 0 0 1-2.27 4.02 46.05 46.05 0 0 1-4.38 4.93 188.52 188.52 0 0 1-6.95 6.55L20 35.58Zm0-4.5c2.67-2.39 4.86-4.43 6.58-6.14 1.73-1.7 3.09-3.2 4.09-4.46 1-1.26 1.7-2.39 2.08-3.38.39-.98.58-1.96.58-2.93a5.65 5.65 0 0 0-5.83-5.83c-1.3 0-2.51.36-3.63 1.1a5.67 5.67 0 0 0-2.29 2.81h-3.16a5.67 5.67 0 0 0-2.3-2.81 6.45 6.45 0 0 0-3.62-1.1 5.65 5.65 0 0 0-5.83 5.83c0 .97.2 1.95.58 2.94.39.98 1.08 2.1 2.08 3.37a52.1 52.1 0 0 0 4.09 4.46c1.72 1.7 3.91 3.76 6.58 6.14Z"/>'
  18.         };
  19.         this.isAuthUser = userData.user;
  20.         this.createHeart();
  21.         this.setAttribute('liked', false);
  22.         if (this.isAuthUser) {
  23.             this.getLikeStatus().then(res=>{
  24.                 if (res.needAuth) {
  25.                     return
  26.                 };
  27.                 this.isLiked = res.is_in_favourites;
  28.                 this.setAttribute('liked', this.isLiked);
  29.                 if (res.is_in_favourites) {
  30.                     if (this.alternativeDesign) {
  31.                         this.button.classList.toggle('like');
  32.                         this.button.classList.toggle('unlike');
  33.                     } else {
  34.                         this.button.classList.add('active');
  35.                     }
  36.                     if (this.isLiked) {
  37.                         this.button.title = this.tippyData[this.isLiked];
  38.                         this.button.setAttribute('data-tippy-main', this.tippyData[this.isLiked]);
  39.                         document.dispatchEvent(new CustomEvent('tippy:update', {detail:{
  40.                             element: this.button,
  41.                             text: this.tippyData[this.isLiked]
  42.                         }}));
  43.                     }
  44.                 }
  45.             });
  46.         }
  47.     }
  48.     createHeart() {
  49.         this.button = this.querySelector('button');
  50.         
  51.         if (this.alternativeDesign) {
  52.             this.button.className = `btn btn-favorite favorite ${this.isLiked ? 'like' : 'unlike'}`;
  53.             
  54.             this.button.innerHTML = `<svg class="btn-favorite-icon" width="40" height="40" fill="none">
  55.                     <path data-like d="m20 35.58-2.42-2.16c-2.8-2.53-5.12-4.71-6.95-6.55a46.04 46.04 0 0 1-4.38-4.93 15.65 15.65 0 0 1-2.27-4.02 11.25 11.25 0 0 1-.65-3.75c0-2.61.88-4.8 2.63-6.54A8.88 8.88 0 0 1 12.5 5 9.88 9.88 0 0 1 20 8.5 9.88 9.88 0 0 1 27.5 5c2.61 0 4.8.88 6.54 2.63a8.88 8.88 0 0 1 2.63 6.54c0 1.27-.22 2.52-.65 3.75a15.63 15.63 0 0 1-2.27 4.02 46.03 46.03 0 0 1-4.38 4.93 188.43 188.43 0 0 1-6.95 6.55L20 35.58Z"/>
  56.                     <path data-unlike d="m20 35.58-2.42-2.16a188.5 188.5 0 0 1-6.95-6.55 46.04 46.04 0 0 1-4.38-4.93 15.65 15.65 0 0 1-2.27-4.02 11.25 11.25 0 0 1-.65-3.75c0-2.61.88-4.8 2.63-6.54A8.88 8.88 0 0 1 12.5 5 9.88 9.88 0 0 1 20 8.5 9.88 9.88 0 0 1 27.5 5c2.61 0 4.8.88 6.54 2.63a8.88 8.88 0 0 1 2.63 6.54c0 1.27-.22 2.52-.65 3.75a15.63 15.63 0 0 1-2.27 4.02 46.05 46.05 0 0 1-4.38 4.93 188.52 188.52 0 0 1-6.95 6.55L20 35.58Zm0-4.5c2.67-2.39 4.86-4.43 6.58-6.14 1.73-1.7 3.09-3.2 4.09-4.46 1-1.26 1.7-2.39 2.08-3.38.39-.98.58-1.96.58-2.93a5.65 5.65 0 0 0-5.83-5.83c-1.3 0-2.51.36-3.63 1.1a5.67 5.67 0 0 0-2.29 2.81h-3.16a5.67 5.67 0 0 0-2.3-2.81 6.45 6.45 0 0 0-3.62-1.1 5.65 5.65 0 0 0-5.83 5.83c0 .97.2 1.95.58 2.94.39.98 1.08 2.1 2.08 3.37a52.1 52.1 0 0 0 4.09 4.46c1.72 1.7 3.91 3.76 6.58 6.14Z"/>
  57.                 </svg>`;
  58.         } else {
  59.             this.button.className = `btn btn-profile btn-profile--like ${this.isLiked ? 'active' : ''}`;
  60.             
  61.             this.button.innerHTML = `<svg class="like-fill" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill="#FF3F40" fill-rule="evenodd" d="M12 4.915c1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.777-3.394 6.855-8.537 11.519l-.013.011-1.45 1.32-1.45-1.31-.04-.036C5.384 15.17 2 12.095 2 8.325c0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09Z" clip-rule="evenodd"/></svg>
  62.                 <svg class="like-border" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"><path fill-rule="evenodd" d="M12 4.915c1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.777-3.394 6.855-8.537 11.519l-.013.011-1.45 1.32-1.45-1.31-.04-.036C5.384 15.17 2 12.095 2 8.325c0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09Zm0 13.56.1-.1c4.76-4.31 7.9-7.16 7.9-10.05 0-2-1.5-3.5-3.5-3.5-1.54 0-3.04.99-3.56 2.36h-1.87c-.53-1.37-2.03-2.36-3.57-2.36-2 0-3.5 1.5-3.5 3.5 0 2.89 3.14 5.74 7.9 10.05l.1.1Z" clip-rule="evenodd"/></svg>`
  63.                 ;
  64.         }
  65.         this.button.addEventListener('click', this);
  66.         this.button.title = this.tippyData[this.isLiked];
  67.         this.button.setAttribute('data-tippy-main', this.tippyData[this.isLiked]);
  68.         this.append(this.button);
  69.         // animation-heart-beat
  70.         const profileAvatar = this.button.closest('[data-favorite-button]');
  71.         if (!profileAvatar) return;
  72.         profileAvatar.addEventListener('mouseover', () => {
  73.             this.button.classList.add('animation-heart-beat');
  74.         });
  75.         profileAvatar.addEventListener('mouseout', () => {
  76.             this.button.classList.remove('animation-heart-beat');
  77.         })
  78.     }
  79.     handleEvent (event) {
  80.         event.preventDefault();
  81.         if (event.type !== 'click') return;
  82.         if (this.alternativeDesign) {
  83.             this.button.classList.toggle('like');
  84.             this.button.classList.toggle('unlike');
  85.         } else {
  86.             this.button.classList.toggle('active');
  87.         }
  88.         if (!this.isAuthUser) {
  89.             window.location = this.getAttribute('registration-url');
  90.             return;
  91.         }
  92.         fetch(this.isLiked ? this.apiUnlike : this.apiLike, {
  93.             headers: {
  94.                 'X-Requested-With': 'XMLHttpRequest',
  95.             },
  96.         })
  97.             .then(res => {
  98.                 this.button.classList.remove('is-loading');
  99.                 if (res.status !== 200) return
  100.                 return res.json();
  101.             })
  102.             .then(data => {
  103.                 if (!data.success) return;
  104.                 if (this.alternativeDesign) {
  105.                     this.button.classList.toggle('unlike', this.isLiked)
  106.                     this.isLiked = !this.isLiked;
  107.                     this.button.classList.toggle('like', this.isLiked)
  108.                 } else {
  109.                     this.isLiked = !this.isLiked;
  110.                     this.button.classList.toggle('active', this.isLiked)
  111.                 }
  112.                 this.button.title = this.tippyData[this.isLiked];
  113.                 this.button.setAttribute('data-tippy-main', this.tippyData[this.isLiked]);
  114.                 document.dispatchEvent(new CustomEvent('tippy:update', {detail:{
  115.                     element: this.button,
  116.                     text: this.tippyData[this.isLiked]
  117.                 }}));
  118.             })
  119.     }
  120.     getLikeStatus() {
  121.         return fetch(this.apiCheck, {
  122.             headers: {
  123.                 'X-Requested-With': 'XMLHttpRequest',
  124.             },
  125.         })
  126.             .then(res => {
  127.                 if (res.status !== 200 || res.redirected) {
  128.                     return {needAuth: true}
  129.                 }
  130.                 return res.json();
  131.             })
  132.             .then(data => {
  133.                 return data;
  134.             })
  135.     }
  136.     //attributeChangedCallback (name, oldValue, newValue) {
  137.         //console.log('attribute changed', name, oldValue, newValue, this);
  138.     //}
  139. });