Guest User

Untitled

a guest
May 3rd, 2025
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.90 KB | None | 0 0
  1. // ==UserScript==
  2. // @name schizophrenia-desktop-notifs (v1.0)
  3. // @namespace violentmonkey‑fullchan‑x
  4. // @match https://8chan.moe/*/res/*.html*
  5. // @match https://8chan.se/*/res/*.html*
  6. // @version 1.0‑2025‑05‑03
  7. // @run-at document-start
  8. // @description Desktop notifs on (You)
  9. // @author schizo75
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. function showNotificationPermissionPrompt() {
  14. if (document.getElementById('fcx-notif-permission')) return; // already shown
  15.  
  16. const box = document.createElement('div');
  17. box.id = 'fcx-notif-permission';
  18. box.style.cssText = `
  19. position: fixed;
  20. bottom: 20px;
  21. right: 20px;
  22. background: #111;
  23. color: white;
  24. padding: 12px 16px;
  25. border-radius: 6px;
  26. box-shadow: 0 4px 12px rgba(0,0,0,0.3);
  27. font-family: sans-serif;
  28. z-index: 9999;
  29. `;
  30.  
  31. box.innerHTML = `
  32. 🔔 Enable desktop notifications?<br>
  33. <button id="fcx-enable-notifs" style="
  34. margin-top: 8px;
  35. padding: 4px 10px;
  36. background: #3a82f7;
  37. color: white;
  38. border: none;
  39. border-radius: 4px;
  40. cursor: pointer;
  41. ">Enable</button>
  42. `;
  43.  
  44. document.body.appendChild(box);
  45.  
  46. document.getElementById('fcx-enable-notifs')?.addEventListener('click', () => {
  47. Notification.requestPermission().then(permission => {
  48. if (permission === 'granted') {
  49. box.remove();
  50. console.log('[FCX] Notifications enabled.');
  51. } else {
  52. box.textContent = '🔕 Notifications disabled.';
  53. setTimeout(() => box.remove(), 3000);
  54. }
  55. });
  56. });
  57. }
  58.  
  59.  
  60. (function monitorYouQuotesWithThrottle() {
  61. const notifiedPostIds = new Set();
  62. let lastNotificationTime = 0;
  63. const MIN_INTERVAL_MS = 60 * 1000; // 1 minute
  64.  
  65. function sendNotification(postId) {
  66. const now = Date.now();
  67. if (now - lastNotificationTime < MIN_INTERVAL_MS) return;
  68. lastNotificationTime = now;
  69.  
  70. new Notification('(You) quoted', {
  71. body: `Your post was quoted in >>${postId}`,
  72. tag: `you-${postId}`,
  73. });
  74. }
  75.  
  76. function handleNewYouQuote(node) {
  77. const link = node.closest('a.quoteLink.you, a.quotelink.you');
  78. if (!link) return;
  79.  
  80. const postEl = link.closest('[id]');
  81. if (!postEl) return;
  82.  
  83. const postId = postEl.id;
  84. if (notifiedPostIds.has(postId)) return;
  85.  
  86. notifiedPostIds.add(postId);
  87.  
  88. if (Notification.permission === 'granted') {
  89. sendNotification(postId);
  90. } else if (Notification.permission === 'default') {
  91. Notification.requestPermission();
  92. }
  93. }
  94.  
  95. function waitForBodyAndStart() {
  96. if (!document.body) {
  97. requestAnimationFrame(waitForBodyAndStart);
  98. return;
  99. }
  100.  
  101. const observer = new MutationObserver(mutations => {
  102. for (const mutation of mutations) {
  103. for (const node of mutation.addedNodes) {
  104. if (!(node instanceof Element)) continue;
  105.  
  106. const youLinks = node.querySelectorAll?.('a.quoteLink.you, a.quotelink.you') || [];
  107. youLinks.forEach(link => handleNewYouQuote(link));
  108.  
  109. if (node.matches?.('a.quoteLink.you, a.quotelink.you')) {
  110. handleNewYouQuote(node);
  111. }
  112. }
  113. }
  114. });
  115.  
  116. observer.observe(document.body, {
  117. childList: true,
  118. subtree: true,
  119. });
  120.  
  121. console.log('[FCX] (You) quote monitor with throttled desktop notifications is active.');
  122. showNotificationPermissionPrompt();
  123.  
  124. }
  125.  
  126. waitForBodyAndStart();
  127. })();
  128.  
  129.  
Advertisement
Add Comment
Please, Sign In to add comment