1// Global variables 2let messageSound = new Audio('notification.mp3'); 3let lastCheckTimestamp = Math.floor(Date.now() / 1000); 4let notificationCount = 0; 5let notificationInterval; 6 7$(document).ready(function() { 8 // Initialize notifications container if it doesn't exist 9 if (!$("#notification-container").length) { 10 $("body").append('<div id="notification-container" style="position: fixed; top: 20px; right: 20px; z-index: 9999;"></div>'); 11 } 12 13 // Add CSS for animation if not already in the document 14 if (!$("#notification-style").length) { 15 $("head").append(` 16 <style id="notification-style"> 17 @keyframes slideIn { 18 from { transform: translateX(100%); opacity: 0; } 19 to { transform: translateX(0); opacity: 1; } 20 } 21 .notification { 22 animation: slideIn 0.3s ease-out; 23 } 24 </style> 25 `); 26 } 27 28 // Initial check for notifications 29 checkNotifications(); 30 updateNotificationBadge(); 31 32 // Set up interval for checking 33 notificationInterval = setInterval(checkNotifications, 10000); // Check every 10 seconds 34 35 $(window).on("beforeunload", function() { 36 clearInterval(notificationInterval); 37 }); 38}); 39 40// Check for new notifications 41function checkNotifications() { 42 $.get("/check_notifications.php?last_check=" + lastCheckTimestamp, function(data) { 43 if (data.status === 'success') { 44 lastCheckTimestamp = data.current_timestamp; 45 46 if (data.notifications && data.notifications.length > 0) { 47 // Play sound only if there are new notifications 48 messageSound.play(); 49 50 data.notifications.forEach(notification => { 51 showNotification(notification); 52 }); 53 54 // Update the notification count 55 updateNotificationBadge(); 56 } 57 } 58 }, "json").fail(function(jqXHR, textStatus, errorThrown) { 59 console.log("Error checking notifications:", textStatus, errorThrown); 60 }); 61} 62 63// Show notification popup 64function showNotification(notification) { 65 const notificationId = `notification-${notification.id}`; 66 67 let viewButton = ''; 68 69 if (notification.link) { 70 // Forum reply with post link 71 viewButton = `<a href="${notification.link}" class="view-message" style="display:inline-block; margin-top: 10px; padding: 5px 10px; background-color: #28a745; color: white; border: none; border-radius: 3px; text-decoration: none;">View</a>`; 72 } else { 73 // Private message (default) 74 viewButton = `<button class="view-message" data-sender="${notification.sender_id}" data-msg-id="${notification.id}" style="margin-top: 10px; padding: 5px 10px; background-color: #28a745; color: white; border: none; border-radius: 3px; cursor: pointer;">View</button>`; 75 } 76 77 const notificationHtml = ` 78 <div id="${notificationId}" class="notification" style="background-color: white; padding: 15px; margin-bottom: 10px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.2); max-width: 300px; position: relative; animation: slideIn 0.3s ease-out;"> 79 <button class="close-notification" style="position: absolute; top: 5px; right: 5px; background: none; border: none; font-size: 16px; cursor: pointer;">Ã</button> 80 <div style="font-weight: bold;">${notification.sender_name}</div> 81 <div style="margin: 5px 0; word-break: break-word;">${notification.message}</div> 82 <div style="font-size: 12px; color: #888;">${new Date(notification.timestamp).toLocaleTimeString()}</div> 83 ${viewButton} 84 </div> 85 `; 86 87 $("#notification-container").prepend(notificationHtml); 88 89 // Auto-dismiss after 20 seconds 90 setTimeout(function() { 91 $(`#${notificationId}`).fadeOut(300, function() { 92 $(this).remove(); 93 }); 94 }, 20000); 95} 96 97 98// Update the notification badge/count 99function updateNotificationBadge() { 100 $.get("get_unread_count.php", function(data) { 101 if (data.status === 'success') { 102 notificationCount = data.count; 103 104 // Update or create badge 105 if (notificationCount > 0) { 106 // If badge doesn't exist, create it 107 if (!$("#msg-badge").length) { 108 $("body").append(` 109 <a href="https://gamble-galaxy.com/notifications.php"><div id="msg-badge" style="position: fixed; bottom: 80px; right: 20px; background-color: #f44336; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.2);"> 110 ${notificationCount} 111 </div></a> 112 `); 113 } else { 114 // Update existing badge 115 $("#msg-badge").text(notificationCount); 116 $("#msg-badge").show(); 117 } 118 } else { 119 // Hide badge if count is 0 120 $("#msg-badge").hide(); 121 } 122 } 123 }, "json"); 124} 125 126// Mark message as read 127function markMessageAsRead(messageId) { 128 $.post("mark_as_read.php", { message_id: messageId }, function(response) { 129 console.log("Message marked as read:", response); 130 }, "json").fail(function(jqXHR, textStatus, errorThrown) { 131 console.log("Error marking message as read:", textStatus, errorThrown); 132 });
133} 134 135// Event delegation for notification buttons 136$(document).on("click", ".close-notification", function() { 137 $(this).closest(".notification").fadeOut(300, function() { 138 $(this).remove(); 139 }); 140}); 141 142 143 144// Function to open the messaging UI on profile page 145function openProfileMessaging(contactId) { 146 // Show the messaging section (adjust selector based on your profile page structure) 147 $("#messaging-section").show(); 148 149 // Set the selected contact 150 $("#contact").val(contactId).change(); 151 152 // Scroll to the messaging section if needed 153 document.getElementById("messaging-section").scrollIntoView({ behavior: "smooth" }); 154} 155 156 157 158 159 160$(document).on("click", ".view-message", function() { 161 162 163 164 const senderId = $(this).data("sender"); 165 const messageId = $(this).data("msg-id"); 166 167 if (window.location.pathname.includes("profile.php")) { 168 $("#contact").val(senderId).change(); 169 170 markMessageAsRead(messageId); 171 $(this).closest(".notification").remove(); 172 updateNotificationBadge(); 173 174 // Wait for messages to load before scrolling 175 setTimeout(function() { 176 const messageElement = $("#message-" + messageId); 177 if (messageElement.length) { 178 messageElement[0].scrollIntoView({ behavior: "smooth", block: "start" }); 179 } else { 180 $("#message-box").scrollTop($("#message-box")[0].scrollHeight); 181 } 182 }, 1000); 183 } else { 184 window.location.href = "profile.php?sender_id=" + senderId; 185 } 186}); 187 188 189
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.