PageSourceSearch

https://thehiddenjams.org/assets/controllers/request_artist_modal_controller-5f56b049.js

js thehiddenjams.org collected 2026-10-04 05:29:57 UTC 3,407 bytes, 92 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2import { sendAnalyticsEvent } from "services/analytics_service"
3
4export default class extends Controller {
5  static targets = ["formScreen", "sendingScreen", "successScreen", "requestedArtistsList"]
6  static values = { cancelRedirects: Boolean }
7
8  async submit(e) {
9    e?.preventDefault()
10    const names = this.getArtistNames()
11    if (names.length === 0) return
12
13    this.submittedArtists = names
14    this.showScreen("sending")
15
16    const csrfToken = document.querySelector("meta[name=\"csrf-token\"]")?.getAttribute("content")
17    const formData = new FormData()
18    formData.append("authenticity_token", csrfToken)
19    names.forEach((name) => formData.append("artist_names[]", name))
20
21    try {
22      const res = await fetch("/artist-requests.json", {
23        method: "POST",
24        body: formData,
25        headers: { "X-Requested-With": "XMLHttpRequest", "Accept": "application/json" },
26      })
27      const data = await res.json().catch(() => ({}))
28      if (res.ok && data.success) {
29        sendAnalyticsEvent("artist_request_submitted", { requested_count: names.length })
30        this.renderRequestedArtists(names)
31        this.showScreen("success")
32      } else {
33        sendAnalyticsEvent("artist_request_failed", {
34          requested_count: names.length,
35          error_type: res.ok ? "server_rejected" : "http_error"
36        })
37        this.showScreen("form")
38        alert(data.error || "Something went wrong. Please try again.")
39      }
40    } catch (err) {
41      sendAnalyticsEvent("artist_request_failed", { requested_count: names.length, error_type: "network_error" })
42      this.showScreen("form")
43      alert("Something went wrong. Please try again.")
44    }
45  }
46
47  getArtistNames() {
48    const inputs = this.formScreenTarget.querySelectorAll(".request-artist-input")
49    return Array.from(inputs)
50      .map((el) => el.value?.trim())
51      .filter(Boolean)
52  }
53
54  renderRequestedArtists(names) {
55    this.requestedArtistsListTarget.innerHTML = ""
56    const spanClass = "request-artist-input w-full h-10 pl-3 pr-3 py-2.5 rounded-lg bg-[rgba(62,62,62,0.52)] border border-[#262626] text-white text-sm font-chivo flex items-center"
57    names.forEach((name) => {
58      const span = document.createElement("span")
59      span.className = spanClass
60      span.textContent = name
61      this.requestedArtistsListTarget.appendChild(span)
62    })
63  }
64
65  handleCancel(e) {
66    e?.preventDefault()
67    if (this.cancelRedirectsValue) {
68      window.location.href = "/artists"
69    } else {
70      const modalController = this.application.getControllerForElementAndIdentifier(this.element, "modal")
71      if (modalController) modalController.close()
72    }
73  }
74
75  showForm(e) {
76    e?.preventDefault()
77    const formEl = this.formScreenTarget.querySelector('[data-controller*="request-artist-form"]')
78    if (formEl) {
79      const formController = this.application.getControllerForElementAndIdentifier(formEl, "request-artist-form")
80      if (formController?.resetForm) formController.resetForm()
81    }
82    this.showScreen("form")
83  }
84
85  showScreen(name) {
86    this.formScreenTarget.style.display = name === "form" ? "block" : "none"
87    this.sendingScreenTarget.style.display = name === "sending" ? "block" : "none"
88    if (this.hasSuccessScreenTarget) {
89      this.successScreenTarget.style.display = name === "success" ? "block" : "none"
90    }
91  }
92}

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.