1import { Controller } from "@hotwired/stimulus" 2 3export default class extends Controller { 4 static targets = ["button"] 5 static values = { seconds: Number } 6 7 connect() { 8 this.baseLabel = this.buttonTarget.dataset.label || this.buttonTarget.textContent || "Resend" 9 this.remainingSeconds = this.secondsValue || 60 10 this.disableButton() 11 this.startCountdown() 12 } 13 14 disconnect() { 15 this.stopCountdown() 16 } 17 18 startCountdown() { 19 this.updateButtonLabel() 20 21 this.timer = setInterval(() => { 22 this.remainingSeconds -= 1 23 24 if (this.remainingSeconds <= 0) { 25 this.stopCountdown() 26 this.enableButton() 27 } else { 28 this.updateButtonLabel() 29 } 30 }, 1000) 31 } 32 33 stopCountdown() { 34 if (this.timer) { 35 clearInterval(this.timer) 36 this.timer = null 37 } 38 } 39 40 resend(event) { 41 if (this.buttonTarget.classList.contains("pointer-events-none")) { 42 event.preventDefault() 43 return 44 } 45 46 this.remainingSeconds = this.secondsValue || 60 47 this.disableButton() 48 this.startCountdown() 49 } 50 51 disableButton() { 52 this.buttonTarget.classList.add("opacity-50", "cursor-not-allowed", "pointer-events-none") 53 this.updateButtonLabel() 54 } 55 56 enableButton() { 57 this.buttonTarget.classList.remove("opacity-50", "cursor-not-allowed", "pointer-events-none") 58 this.buttonTarget.textContent = this.baseLabel 59 } 60 61 updateButtonLabel() { 62 const label = `${this.baseLabel} (${this.remainingSeconds}s)` 63 this.buttonTarget.textContent = label 64 } 65}
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.