1// app/javascript/controllers/notifications_controller.js 2import { Controller } from "@hotwired/stimulus" 3 4export default class extends Controller { 5 static targets = ["dropdown"] 6 7 markAsRead() { 8 // Only make the request if we have unread notifications. The bell dot shows 9 // no number, so the count rides on data-unread-count (a red "!" dot can sit 10 // on a bell with nothing unread). 11 const indicator = document.getElementById("notification-indicator") 12 if (indicator && Number(indicator.dataset.unreadCount) > 0) { 13 // Request the turbo-stream response (a 200, not a 302 â fetch keeps the 14 // PATCH method across a redirect-follow, which used to re-PATCH 15 // /notifications, 404, and leave the badge visible â MSJD-245). The 16 // stream re-renders the bell dot (green clears; a red "!" stays until 17 // the cases/Stripe problem are fixed) and refreshes #notification-list when on the index page. 18 fetch("/notifications/mark_as_read", { 19 method: "PATCH", 20 headers: { 21 "X-CSRF-Token": this.csrfToken(), 22 "Accept": "text/vnd.turbo-stream.html", 23 "Content-Type": "application/json" 24 }, 25 credentials: "same-origin" 26 }) 27 .then(response => response.ok ? response.text() : null) 28 .then(html => { 29 if (html) { 30 Turbo.renderStreamMessage(html) 31 } 32 }) 33 } 34 } 35 36 markOneAsRead(event) { 37 event.preventDefault() 38 const url = event.currentTarget.getAttribute("href") || event.currentTarget.closest("form")?.action 39 if (!url) return 40 41 fetch(url, { 42 method: "PATCH", 43 headers: { 44 "X-CSRF-Token": this.csrfToken(), 45 "Accept": "text/vnd.turbo-stream.html", 46 "Content-Type": "application/json" 47 }, 48 credentials: "same-origin" 49 }) 50 .then(response => { 51 if (response.ok) { 52 return response.text() 53 } 54 }) 55 .then(html => { 56 if (html) { 57 Turbo.renderStreamMessage(html) 58 } 59 }) 60 } 61 62 dismiss(event) { 63 event.preventDefault() 64 const notificationEl = event.currentTarget.closest("[id^='notification_']") 65 const url = event.currentTarget.getAttribute("href") || event.currentTarget.closest("form")?.action 66 if (!url) return 67 68 fetch(url, { 69 method: "DELETE", 70 headers: { 71 "X-CSRF-Token": this.csrfToken(), 72 "Accept": "text/vnd.turbo-stream.html", 73 "Content-Type": "application/json" 74 }, 75 credentials: "same-origin" 76 }) 77 .then(response => { 78 if (response.ok && notificationEl) { 79 notificationEl.remove() 80 } 81 }) 82 } 83 84 // The meta tag is absent when CSRF protection is disabled (e.g. test env) â 85 // don't crash the whole action on the lookup. 86 csrfToken() { 87 return document.querySelector("meta[name='csrf-token']")?.content ?? "" 88 } 89};
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.