auctions-1.0.x-dev/modules/auctions_core/js/drupal.behaviors.auctionBidRefresh.js
modules/auctions_core/js/drupal.behaviors.auctionBidRefresh.js
(function($, Drupal) { 'use strict'; /** * Attaches the JS Bid refresh Behaviour */ Drupal.behaviors.auctionBidRefresh = { attach: function(context) { $(once('auction-bid-refresh-active', '.auctions-core-bidders', context)).each(function() { var $bidRefresher = $(this); var $input = $bidRefresher.find('#edit-amount'); var $button = $bidRefresher.find('button'); var $submit = $bidRefresher.find('[data-drupal-selector="edit-submit"]'); var $promiseMarker = $button.find('.refresh-promise'); var rate = $button.data('rate'); var adrenalineRate = $button.data('adrenaline'); var until = $button.data('until'); let auctionItem = $button.data('auction-item'); let currentState = $button.attr('aria-pressed'); $input.focus(function() { if (currentState) { $input.addClass('refresh-pause'); $promiseMarker.removeClass('active'); } }).blur(function() { if (currentState) { $input.removeClass('refresh-pause'); $promiseMarker.addClass('active'); } }); $promiseMarker.on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function() { $(this).removeClass('pulse').removeClass('spin').removeClass('inherit'); }); // Refresh initialization $button.click(function() { let $button = $(this); // Toggle the aria-pressed attribute. $button.attr('aria-pressed', function(index, value) { currentState = value === 'true' ? false : true; return currentState; }); // Toggle the class of the .refresh-promise element. if (currentState === true) { $promiseMarker.addClass('active').addClass('pulse'); } else { $promiseMarker.removeClass('active'); } }); // Form Submit watcher. Stop refresh during normal html form submits. $submit.click(function() { $button.attr({ 'aria-pressed': false }); $input.addClass('refresh-pause'); }); // Start a routine to periodically fetch data function bidRefreshCycle(auctionItem, rate, currentState) { if (!currentState) { //console.log('Refresh State Disabled'); return; } // Dynamic rate adjustment based on certain conditions let dynamicRate = Drupal.auctionBidRefresh.refreshAdrenaline(rate, adrenalineRate, until); Drupal.auctionBidRefresh.refresh(auctionItem) .then(() => { //console.log('Refresh successful'); }) .catch((error) => { // Note: most returns 200-400ms. //console.error('Refresh failed: ', error); dynamicRate = rate - .5 > 1 ? rate - .5 : 1; }) .finally(() => { // Schedule the next refresh setTimeout(() => bidRefreshCycle(auctionItem, rate, currentState), dynamicRate * 1000); }); }; // Begin refresh Cycles. bidRefreshCycle(auctionItem, rate, currentState); }); } }; /** * Init namespace. */ Drupal.auctionBidRefresh = Drupal.auctionBidRefresh || {}; Drupal.auctionBidRefresh.refresh = async function(auctionItem) { try { const response = await $.ajax({ url: "/system/auction-item-refresh/" + auctionItem, type: "GET", contentType: 'application/json; charset=utf-8', timeout: 0, cache: false, }); // Update UI based on response Drupal.auctionBidRefresh.refreshDisplay(response, auctionItem); } catch (error) { // console.error('Error fetching auction item data: ', error); throw error; // Rethrow the error for the caller to handle } }; // UI update logic based on response data Drupal.auctionBidRefresh.refreshDisplay = function(data, auctionItem) { $('.current-formatted').html(data.formattedPrice); $('.auctions-core-bidders[data-auction-item=' + auctionItem + '] [data-drupal-selector="edit-status"]').html(data.selfBid); var $input = $('.auctions-core-bidders[data-auction-item=' + auctionItem + '] [data-drupal-selector="edit-amount"]'); $input.prop('disabled', false); var $button = $('.auctions-core-bidders[data-auction-item=' + auctionItem + ']').find('button'); var lastRun = $('.auctions-core-bidders[data-auction-item=' + auctionItem + '] [data-drupal-selector="edit-amount"]').data('refresh'); var useClass = 'spin'; if (data.refreshAmount > lastRun) { if (!$input.hasClass('refresh-pause') || $button.attr('aria-pressed') !== 'true') { useClass = 'pulse'; $input.attr({ "value": data.refreshAmount, "min": data.minPrice, 'aria-live': 'polite' }) .data('refresh', data.refreshAmount); } else { useClass = 'inherit'; } } // Trigger anim of promise svg. $('.auctions-core-bidders[data-auction-item=' + auctionItem + '] .refresh-promise').addClass(useClass); }; Drupal.auctionBidRefresh.refreshAdrenaline = function(rate, adrenalineRate, until) { let tick = rate; var left = Math.floor(((until * 1000) - (new Date())) / 1000); // if past time, tick will return to orginal rate. if (left < adrenalineRate && left > -1) { tick = 1; } return tick; }; })(jQuery, Drupal);