1import {Controller} from '@hotwired/stimulus'; 2import axios from 'axios'; 3import flash from '../../libs/flashes.js'; 4 5/* stimulusFetch: 'lazy' */ 6export default class extends Controller { 7 static values = { 8 cooldownSeconds: {type: Number, default: 30}, 9 idleLabel: String, 10 countdownLabel: String, 11 successMessage: String, 12 errorMessage: String, 13 }; 14 15 async reSend(event) { 16 const button = event.currentTarget; 17 if (button.disabled) { 18 return; 19 } 20 21 const idleLabel = this.idleLabelValue || button.textContent.trim(); 22 this.idleLabelValue = idleLabel; 23 24 button.disabled = true; 25 button.classList.remove('btn-primary'); 26 button.classList.add('btn-error'); 27 28 const url = button.dataset.url; 29 try { 30 await axios.post(url); 31 flash('success', this.successMessageValue); 32 } catch (error) { 33 flash('error', this.errorMessageValue); 34 } 35 36 this.startCountdown(button); 37 } 38 39 startCountdown(button) { 40 let remaining = this.cooldownSecondsValue; 41 this.updateLabel(button, remaining); 42 43 const interval = setInterval(() => { 44 remaining -= 1; 45 if (remaining <= 0) { 46 clearInterval(interval); 47 button.textContent = this.idleLabelValue; 48 button.disabled = false; 49 button.classList.remove('btn-error'); 50 button.classList.add('btn-primary'); 51 return; 52 } 53 this.updateLabel(button, remaining); 54 }, 1000); 55 } 56 57 updateLabel(button, seconds) { 58 const template = this.countdownLabelValue || `${this.idleLabelValue} (${seconds}s)`; 59 button.textContent = template.replace('%s', seconds); 60 } 61}
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.