PageSourceSearch

https://damarturkfm.com.tr/assets/site/request-line.js?v=8.5.5

js damarturkfm.com.tr collected 2026-10-02 01:09:11 UTC 10,484 bytes, 188 lines download raw bytes

1/* RSH İstek Hattı — React/player yaşam döngüsünden tamamen bağımsız modül. */
2(() => {
3  'use strict';
4
5  const ENDPOINT = '/api/v1/request-line.php';
6  const DEFAULT_CLOSED = 'Şu anda yeni şarkı isteği kabul edemiyoruz. İstek hattımız tekrar aktif olduğunda bize buradan ulaşabilirsiniz. Lütfen daha sonra yeniden deneyin.';
7  let active = false;
8  let closedMessage = DEFAULT_CLOSED;
9  let lastFocus = null;
10
11  const ready = (callback) => document.readyState === 'loading'
12    ? document.addEventListener('DOMContentLoaded', callback, { once: true })
13    : callback();
14
15  ready(() => {
16    if (document.querySelector('[data-rsh-request-line]')) return;
17
18    const modal = document.createElement('div');
19    modal.className = 'rshRequestModal';
20    modal.dataset.rshRequestLine = 'modal';
21    modal.hidden = true;
22    modal.innerHTML = `
23      <button class="rshRequestModal__backdrop" type="button" data-request-close aria-label="Pencereyi kapat"></button>
24      <section class="rshRequestModal__dialog" role="dialog" aria-modal="true" aria-labelledby="rsh-request-title">
25        <button class="rshRequestModal__close" type="button" data-request-close aria-label="Pencereyi kapat"><span aria-hidden="true">×</span></button>
26        <header class="rshRequestModal__header">
27          <span class="rshRequestModal__icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 18V5l11-2v13M9 18a3 3 0 1 1-3-3c1.7 0 3 1.3 3 3Zm11-2a3 3 0 1 1-3-3c1.7 0 3 1.3 3 3Z"/></svg></span>
28          <div><small>CANLI YAYIN</small><h2 id="rsh-request-title">İstek Hattı</h2><p>Dinlemek istediğiniz şarkıyı stüdyomuza iletin.</p></div>
29        </header>
30        <div class="rshRequestState rshRequestState--closed" hidden>
31          <span class="rshRequestState__icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 13a2 2 0 1 0 0-4 2 2 0 0 0 0 4Zm-5.7 6.7a11 11 0 0 1 0-15.4m11.4 0a11 11 0 0 1 0 15.4M9.1 16.9a7 7 0 0 1 0-9.8m5.8 0a7 7 0 0 1 0 9.8M12 13v8"/></svg></span>
32          <small>ŞU ANDA ÇEVRİMDIŞI</small><h3>İstek Hattımız Şu Anda Kapalı</h3><p data-closed-copy></p>
33        </div>
34        <form class="rshRequestForm" novalidate>
35          <label><span>Ad Soyad</span><input name="name" type="text" minlength="2" maxlength="100" autocomplete="name" placeholder="Adınız ve soyadınız" required></label>
36          <label><span>İstek Şarkı</span><input name="song" type="text" minlength="2" maxlength="160" autocomplete="off" placeholder="Sanatçı – Şarkı adı" required></label>
37          <label><span>Mesaj <em>İsteğe bağlı</em></span><textarea name="message" rows="4" maxlength="1000" placeholder="Yayıncıya iletmek istediğiniz kısa mesaj"></textarea><small data-message-count>0 / 1000</small></label>
38          <input class="rshRequestForm__trap" name="website" type="hidden" value="" aria-hidden="true">
39          <label class="rshRequestForm__consent"><input name="consent" type="checkbox" value="1" required><span>Gönderdiğim bilgilerin istek talebimin değerlendirilmesi amacıyla kullanılmasını kabul ediyorum.</span></label>
40          <div class="rshRequestForm__notice" role="status" aria-live="polite"></div>
41          <button class="rshRequestForm__submit" type="submit"><span>İsteği Gönder</span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg></button>
42        </form>
43        <div class="rshRequestState rshRequestState--success" hidden>
44          <span class="rshRequestState__icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></span>
45          <small>İSTEK ALINDI</small><h3>Teşekkür ederiz.</h3><p>İsteğiniz başarıyla alındı. Teşekkür ederiz.</p>
46          <button type="button" data-request-close>Tamam</button>
47        </div>
48      </section>`;
49    document.body.appendChild(modal);
50
51    const form = modal.querySelector('.rshRequestForm');
52    const closed = modal.querySelector('.rshRequestState--closed');
53    const success = modal.querySelector('.rshRequestState--success');
54    const notice = modal.querySelector('.rshRequestForm__notice');
55    const submit = modal.querySelector('.rshRequestForm__submit');
56    const textarea = form.elements.message;
57    const counter = modal.querySelector('[data-message-count]');
58
59    const close = () => {
60      modal.classList.remove('is-open');
61      document.documentElement.classList.remove('rshRequestModalOpen');
62      window.setTimeout(() => { modal.hidden = true; lastFocus?.focus?.(); }, 220);
63    };
64    const open = (trigger) => {
65      lastFocus = trigger;
66      modal.hidden = false;
67      form.hidden = !active;
68      closed.hidden = active;
69      success.hidden = true;
70      modal.querySelector('[data-closed-copy]').textContent = closedMessage;
71      notice.textContent = '';
72      requestAnimationFrame(() => {
73        modal.classList.add('is-open');
74        document.documentElement.classList.add('rshRequestModalOpen');
75      });
76      window.setTimeout(() => (active ? form.elements.name : modal.querySelector('[data-request-close]'))?.focus(), 90);
77    };
78
79    modal.querySelectorAll('[data-request-close]').forEach((button) => button.addEventListener('click', close));
80    document.addEventListener('keydown', (event) => { if (event.key === 'Escape' && !modal.hidden) close(); });
81    textarea.addEventListener('input', () => { counter.textContent = `${textarea.value.length} / 1000`; });
82
83    form.addEventListener('submit', async (event) => {
84      event.preventDefault();
85      notice.textContent = '';
86      if (!form.reportValidity()) return;
87      submit.disabled = true;
88      submit.querySelector('span').textContent = 'Gönderiliyor';
89      try {
90        const payload = Object.fromEntries(new FormData(form).entries());
91        payload.consent = form.elements.consent.checked;
92        const response = await fetch(ENDPOINT, {
93          method: 'POST', cache: 'no-store', credentials: 'same-origin',
94          headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
95          body: JSON.stringify(payload)
96        });
97        const result = await response.json().catch(() => ({}));
98        if (!response.ok) throw new Error(result.error || 'İstek gönderilemedi. Lütfen yeniden deneyin.');
99        form.reset(); counter.textContent = '0 / 1000'; form.hidden = true; success.hidden = false;
100      } catch (error) {
101        notice.textContent = error?.message || 'İstek gönderilemedi. Lütfen yeniden deneyin.';
102      } finally {
103        submit.disabled = false;
104        submit.querySelector('span').textContent = 'İsteği Gönder';
105      }
106    });
107
108    const launcher = document.createElement('button');
109    launcher.type = 'button';
110    launcher.className = 'rshRequestLauncher';
111    launcher.dataset.rshRequestLine = 'launcher';
112    launcher.setAttribute('aria-haspopup', 'dialog');
113    launcher.setAttribute('aria-label', 'İstek Gönder');
114    // Durum API'den doğrulanana kadar mobil butonu göstermeyerek kısa süreli
115    // görünme/kaybolma (flash) etkisini önler. WhatsApp bu durumdan bağımsızdır.
116    launcher.hidden = true;
117    launcher.innerHTML = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 18V5l11-2v13M9 18a3 3 0 1 1-3-3c1.7 0 3 1.3 3 3Zm11-2a3 3 0 1 1-3-3c1.7 0 3 1.3 3 3Z"/></svg><span>İstek Gönder</span>';
118    launcher.addEventListener('click', () => open(launcher));
119
120    const playerLauncher = document.createElement('button');
121    playerLauncher.type = 'button';
122    playerLauncher.className = 'rshRequestPlayerButton';
123    playerLauncher.dataset.rshRequestLine = 'player-launcher';
124    playerLauncher.setAttribute('aria-haspopup', 'dialog');
125    playerLauncher.setAttribute('aria-label', 'İstek Gönder');
126    playerLauncher.innerHTML = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 18V5l11-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="17" cy="16" r="3"/></svg><span>İstek Hattı</span>';
127    playerLauncher.addEventListener('click', () => open(playerLauncher));
128
129    const fallback = document.createElement('div');
130    fallback.className = 'rshRequestDock';
131    fallback.appendChild(launcher);
132    document.body.appendChild(fallback);
133
134    /* React ağacını izlemek yerine kısa süreli ve zararsız polling kullanılır. */
135    let attempts = 0;
136    const attachNearWhatsApp = () => {
137      attempts += 1;
138      const whatsapp = document.querySelector('.waMessenger');
139      const whatsappButton = whatsapp?.querySelector('.waLauncher');
140      if (whatsapp && whatsappButton) {
141        const label = whatsappButton.querySelector('span');
142        if (label && label.textContent !== 'WhatsApp') label.textContent = 'WhatsApp';
143        if (launcher.parentElement !== whatsapp || launcher.nextElementSibling !== whatsappButton) {
144          whatsapp.insertBefore(launcher, whatsappButton);
145        }
146        fallback.remove();
147        return true;
148      }
149      return false;
150    };
151    if (!attachNearWhatsApp()) {
152      const timer = window.setInterval(() => {
153        if (attachNearWhatsApp() || attempts >= 40) window.clearInterval(timer);
154      }, 500);
155    }
156
157    let playerAttempts = 0;
158    const attachToPlayer = () => {
159      playerAttempts += 1;
160      const controls = document.querySelector('.radioDockV2__controls');
161      const play = controls?.querySelector('.radioDockV2__play');
162      if (!controls || !play) return false;
163      if (playerLauncher.parentElement !== controls || playerLauncher.nextElementSibling !== play) controls.insertBefore(playerLauncher, play);
164      return true;
165    };
166    if (!attachToPlayer()) {
167      const playerTimer = window.setInterval(() => {
168        if (attachToPlayer() || playerAttempts >= 40) window.clearInterval(playerTimer);
169      }, 500);
170    }
171
172    fetch(ENDPOINT, { cache: 'no-store', credentials: 'same-origin', headers: { Accept: 'application/json' } })
173      .then((response) => response.ok ? response.json() : Promise.reject())
174      .then((payload) => {
175        active = payload?.data?.active === true;
176        closedMessage = payload?.data?.closed_message || DEFAULT_CLOSED;
177        // Bu launcher mobilde WhatsApp'ın yanında görünen İstek Hattı
178        // butonudur. Hat kapalıysa yalnızca bu buton gizlenir; WhatsApp'a
179        // hiçbir sınıf, stil veya görünürlük değişikliği uygulanmaz.
180        launcher.hidden = !active;
181      })
182      .catch(() => {
183        active = false;
184        closedMessage = DEFAULT_CLOSED;
185        launcher.hidden = true;
186      });
187  });
188})();

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.