aboutsummaryrefslogtreecommitdiffstats
path: root/view/tpl
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2024-12-19 18:49:07 +0000
committerMario <mario@mariovavti.com>2024-12-19 18:49:07 +0000
commita2dde34b1be35282618035652f919c39199beea1 (patch)
tree128d7fb247fc463cc5dc403da8ecc1928c138c29 /view/tpl
parentfb5824417e12710572b8786f1db2e75457819447 (diff)
downloadvolse-hubzilla-a2dde34b1be35282618035652f919c39199beea1.tar.gz
volse-hubzilla-a2dde34b1be35282618035652f919c39199beea1.tar.bz2
volse-hubzilla-a2dde34b1be35282618035652f919c39199beea1.zip
refactor notifications widget and updateConvItems() to not require jquery
Diffstat (limited to 'view/tpl')
-rw-r--r--view/tpl/notifications_widget.tpl758
1 files changed, 462 insertions, 296 deletions
diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl
index c1d7edd66..1ad054d37 100644
--- a/view/tpl/notifications_widget.tpl
+++ b/view/tpl/notifications_widget.tpl
@@ -8,42 +8,52 @@
var sse_sys_only = {{$sys_only}};
$(document).ready(function() {
- let notifications_parent;
- if ($('#notifications_wrapper').length) {
- notifications_parent = $('#notifications_wrapper')[0].parentElement.id;
- }
-
- $('.notifications-btn').click(function() {
- $('#notifications_wrapper').removeClass('d-none');
-
- if($('#notifications_wrapper').hasClass('fs')) {
- $('#notifications_wrapper').prependTo('#' + notifications_parent);
- $('#notifications_wrapper').addClass('d-none');
+ let notificationsWrapper = document.getElementById('notifications_wrapper');
+ let notificationsParent = notificationsWrapper.parentElement.id;
+ let notificationsBtn = document.querySelector('.notifications-btn');
+
+ // Event listener for notifications button
+ if (notificationsBtn) {
+ notificationsBtn.addEventListener('click', function() {
+ // Remove the 'd-none' class to show the notifications wrapper
+ notificationsWrapper.classList.remove('d-none');
+
+ // Check if the notifications wrapper has the 'fs' class
+ if (notificationsWrapper.classList.contains('fs')) {
+ // Prepend the notifications wrapper back to its original parent and hide it
+ document.getElementById(notificationsParent).appendChild(notificationsWrapper);
+ notificationsWrapper.classList.add('d-none');
+ } else {
+ // Otherwise, prepend the notifications wrapper to 'main'
+ document.querySelector('main').prepend(notificationsWrapper);
+ }
- }
- else {
- $('#notifications_wrapper').prependTo('main');
- }
+ // Toggle the 'fs' class
+ notificationsWrapper.classList.toggle('fs');
+ });
+ }
- $('#notifications_wrapper').toggleClass('fs');
- if($('#navbar-collapse-2').hasClass('show')){
- $('#navbar-collapse-2').removeClass('show');
- }
- });
+ // Event listener for clicking a notification
+ document.addEventListener('click', function(event) {
+ if (event.target.closest('a') && event.target.closest('a').classList.contains('notification')) {
+ console.log(1)
+ if (notificationsWrapper.classList.contains('fs')) {
+ // Move notifications wrapper back to its original parent and hide it
+ notificationsWrapper.classList.remove('fs');
+ notificationsWrapper.classList.add('d-none');
+ document.getElementById(notificationsParent).appendChild(notificationsWrapper);
- $(document).on('click', '.notification', function() {
- if($('#notifications_wrapper').hasClass('fs')) {
- $('#notifications_wrapper').prependTo('#' + notifications_parent).removeClass('fs').addClass('d-none');
+ }
}
});
if(sse_enabled) {
if(typeof(window.SharedWorker) === 'undefined') {
// notifications with multiple tabs open will not work very well in this scenario
- var evtSource = new EventSource('/sse');
+ let evtSource = new EventSource('/sse');
evtSource.addEventListener('notifications', function(e) {
- var obj = JSON.parse(e.data);
+ let obj = JSON.parse(e.data);
sse_handleNotifications(obj, false, false);
}, false);
@@ -56,7 +66,7 @@
}
else {
- var myWorker = new SharedWorker('/view/js/sse_worker.js', localUser);
+ let myWorker = new SharedWorker('/view/js/sse_worker.js', localUser);
myWorker.port.onmessage = function(e) {
obj = e.data;
@@ -72,8 +82,9 @@
}
}
else {
- if (!document.hidden)
+ if (!document.hidden) {
sse_fallback_interval = setInterval(sse_fallback, updateInterval);
+ }
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
@@ -88,234 +99,338 @@
}, false);
}
- $('.notification-link').on('click', { replace: true, followup: false }, sse_bs_notifications);
-
- $('.notification-filter').on('keypress', function(e) {
- if(e.which == 13) { // enter
- this.blur();
- sse_offset = 0;
- $("#nav-" + sse_type + "-menu").html('');
- $("#nav-" + sse_type + "-loading").show();
-
- var cn_val = $('#cn-' + sse_type + '-input').length ? $('#cn-' + sse_type + '-input').val().toString().toLowerCase() : '';
-
- $.get('/sse_bs/' + sse_type + '/' + sse_offset + '?nquery=' + encodeURIComponent(cn_val), function(obj) {
- console.log('sse: bootstraping ' + sse_type);
- console.log(obj);
-
- sse_bs_active = false;
- sse_partial_result = true;
- sse_offset = obj[sse_type].offset;
- if(sse_offset < 0)
- $("#nav-" + sse_type + "-loading").hide();
+ document.querySelectorAll('.notification-link').forEach(function (element) {
+ element.addEventListener('click', function (element) {
+ sse_bs_notifications(element, true, false);
+ });
+ });
- sse_handleNotifications(obj, true, false);
+ document.querySelectorAll('.notification-filter').forEach(function (element) {
+ element.addEventListener('keypress', function(e) {
+ if (e.which == 13) { // Enter key
+ this.blur();
+ sse_offset = 0;
- });
- }
+ // Clear the content of the menu
+ document.getElementById("nav-" + sse_type + "-menu").innerHTML = '';
+
+ // Show the loading element
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
+
+ // Get the value from the input element
+ var cn_val = document.getElementById('cn-' + sse_type + '-input') ? document.getElementById('cn-' + sse_type + '-input').value.toString().toLowerCase() : '';
+
+ // Send a GET request using the Fetch API
+ fetch('/sse_bs/' + sse_type + '/' + sse_offset + '?nquery=' + encodeURIComponent(cn_val))
+ .then(response => response.json())
+ .then(obj => {
+ console.log('sse: bootstraping ' + sse_type);
+ console.log(obj);
+
+ sse_bs_active = false;
+ sse_partial_result = true;
+ sse_offset = obj[sse_type].offset;
+ if (sse_offset < 0) {
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
+ }
+
+ sse_handleNotifications(obj, true, false);
+ })
+ .catch(error => {
+ console.error('Error fetching data:', error);
+ });
+ }
+ });
});
- $('.notifications-textinput-clear').on('click', function(e) {
- if(! sse_partial_result)
- return;
+ document.querySelectorAll('.notifications-textinput-clear').forEach(function (element) {
+ element.addEventListener('click', function(e) {
+ if (!sse_partial_result) return;
- $("#nav-" + sse_type + "-menu").html('');
- $("#nav-" + sse_type + "-loading").show();
- $.get('/sse_bs/' + sse_type, function(obj) {
- console.log('sse: bootstraping ' + sse_type);
- console.log(obj);
+ // Clear the content of the menu
+ document.getElementById("nav-" + sse_type + "-menu").innerHTML = '';
+
+ // Show the loading element
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
- sse_bs_active = false;
- sse_partial_result = false;
- sse_offset = obj[sse_type].offset;
- if(sse_offset < 0)
- $("#nav-" + sse_type + "-loading").hide();
+ // Send a GET request using the Fetch API
+ fetch('/sse_bs/' + sse_type)
+ .then(response => response.json())
+ .then(obj => {
+ console.log('sse: bootstraping ' + sse_type);
+ console.log(obj);
- sse_handleNotifications(obj, true, false);
+ sse_bs_active = false;
+ sse_partial_result = false;
+ sse_offset = obj[sse_type].offset;
+ if (sse_offset < 0) {
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
+ }
+ sse_handleNotifications(obj, true, false);
+ })
+ .catch(error => {
+ console.error('Error fetching data:', error);
+ });
});
});
- $('.notification-content').on('scroll', function() {
- if(this.scrollTop > this.scrollHeight - this.clientHeight - (this.scrollHeight/7)) {
- sse_bs_notifications(sse_type, false, true);
- }
+ document.querySelectorAll('.notification-content').forEach(function(element) {
+ element.addEventListener('scroll', function() {
+ if (this.scrollTop > this.scrollHeight - this.clientHeight - (this.scrollHeight / 7)) {
+ sse_bs_notifications(sse_type, false, true);
+ }
+ });
});
});
- $(document).on('hz:sse_setNotificationsStatus', function(e, data) {
- sse_setNotificationsStatus(data);
+ document.addEventListener('hz:sse_setNotificationsStatus', function(e) {
+ sse_setNotificationsStatus(e.detail);
});
- $(document).on('hz:sse_bs_init', function() {
+ document.addEventListener('hz:sse_bs_init', function() {
sse_bs_init();
});
- $(document).on('hz:sse_bs_counts', function() {
+ document.addEventListener('hz:sse_bs_counts', function() {
sse_bs_counts();
});
+
{{foreach $notifications as $notification}}
{{if $notification.filter}}
- $(document).on('click', '#tt-{{$notification.type}}-only', function(e) {
- if($(this).hasClass('active sticky-top')) {
- $('#nav-{{$notification.type}}-menu .notification[data-thread_top=false]').removeClass('tt-filter-active');
- $(this).removeClass('active sticky-top');
- }
- else {
- $('#nav-{{$notification.type}}-menu .notification[data-thread_top=false]').addClass('tt-filter-active');
- $(this).addClass('active sticky-top');
- // load more notifications if visible notifications count is low
- if(sse_type && sse_offset != -1 && $('#nav-' + sse_type + '-menu').children(':visible').length < 15) {
- sse_bs_notifications(sse_type, false, true);
+ document.addEventListener('click', function(e) {
+ if (e.target.closest('div').matches('#tt-{{$notification.type}}-only')) {
+ let element = e.target.closest('div');
+ let menu = document.querySelector('#nav-{{$notification.type}}-menu');
+ let notifications = menu.querySelectorAll('.notification[data-thread_top="false"]');
+
+ // Function to check if an element is visible
+ function isVisible(el) {
+ return el.offsetWidth > 0 && el.offsetHeight > 0;
}
- }
- });
+ if (element.classList.contains('active') && element.classList.contains('sticky-top')) {
+ notifications.forEach(function(notification) {
+ notification.classList.remove('tt-filter-active');
+ });
+ element.classList.remove('active', 'sticky-top');
+ } else {
+ notifications.forEach(function(notification) {
+ notification.classList.add('tt-filter-active');
+ });
+ element.classList.add('active', 'sticky-top');
- $(document).on('click', '#cn-{{$notification.type}}-input-clear', function(e) {
- $('#cn-{{$notification.type}}-input').val('');
- $('#cn-{{$notification.type}}-only').removeClass('active sticky-top');
- $("#nav-{{$notification.type}}-menu .notification").removeClass('cn-filter-active');
- $('#cn-{{$notification.type}}-input-clear').addClass('d-none');
- });
+ // Count the visible notifications
+ let visibleNotifications = Array.from(menu.querySelectorAll('.notification')).filter(isVisible).length;
- $(document).on('input', '#cn-{{$notification.type}}-input', function(e) {
- var val = $('#cn-{{$notification.type}}-input').val().toString().toLowerCase();
- if(val) {
- val = val.indexOf('%') == 0 ? val.substring(1) : val;
- $('#cn-{{$notification.type}}-only').addClass('active sticky-top');
- $('#cn-{{$notification.type}}-input-clear').removeClass('d-none');
+ // Load more notifications if the visible count is low
+ if (sse_type && sse_offset !== -1 && visibleNotifications < 15) {
+ sse_bs_notifications(sse_type, false, true);
+ }
+ }
}
- else {
- $('#cn-{{$notification.type}}-only').removeClass('active sticky-top');
- $('#cn-{{$notification.type}}-input-clear').addClass('d-none');
+
+ if (e.target.closest('div').matches('#cn-{{$notification.type}}-input-clear')) {
+ // Clear the input value
+ let input = document.querySelector('#cn-{{$notification.type}}-input');
+ input.value = '';
+
+ // Remove the 'active' and 'sticky-top' classes from the clear button
+ let clearButton = e.target;
+ clearButton.classList.remove('active', 'sticky-top');
+
+ // Remove the 'cn-filter-active' class from all notifications
+ let notifications = document.querySelectorAll("#nav-{{$notification.type}}-menu .notification");
+ notifications.forEach(function(notification) {
+ notification.classList.remove('cn-filter-active');
+ });
+
+ // Add the 'd-none' class to hide the clear button
+ clearButton.classList.add('d-none');
}
- $("#nav-{{$notification.type}}-menu .notification").each(function(i, el){
- var cn = $(el).data('contact_name').toString().toLowerCase();
- var ca = $(el).data('contact_addr').toString().toLowerCase();
+ });
- if(cn.indexOf(val) === -1 && ca.indexOf(val) === -1)
- $(this).addClass('cn-filter-active');
- else
- $(this).removeClass('cn-filter-active');
- });
+ document.addEventListener('input', function(e) {
+ // Check if the input element matches the selector
+ if (e.target.matches('#cn-{{$notification.type}}-input')) {
+ let input = e.target;
+ let val = input.value.toString().toLowerCase();
+
+ // Check if there is input value
+ if (val) {
+ // Remove '%' if it's at the beginning of the input value
+ val = val.indexOf('%') === 0 ? val.substring(1) : val;
+
+ // Add 'active' and 'sticky-top' classes to the 'only' element
+ let onlyElement = document.getElementById('cn-{{$notification.type}}-only');
+ onlyElement.classList.add('active', 'sticky-top');
+
+ // Remove 'd-none' class from the clear button
+ let clearButton = document.getElementById('cn-{{$notification.type}}-input-clear');
+ clearButton.classList.remove('d-none');
+ } else {
+ // Remove 'active' and 'sticky-top' classes from the 'only' element
+ let onlyElement = document.getElementById('cn-{{$notification.type}}-only');
+ onlyElement.classList.remove('active', 'sticky-top');
+
+ // Add 'd-none' class to the clear button
+ let clearButton = document.getElementById('cn-{{$notification.type}}-input-clear');
+ clearButton.classList.add('d-none');
+ }
+
+ // Loop through each notification and apply filter logic
+ let notifications = document.querySelectorAll("#nav-{{$notification.type}}-menu .notification");
+ notifications.forEach(function(el) {
+ let cn = el.dataset.contact_name.toString().toLowerCase();
+ let ca = el.dataset.contact_addr.toString().toLowerCase();
+
+ // Check if the contact name or address matches the input value
+ if (cn.indexOf(val) === -1 && ca.indexOf(val) === -1) {
+ el.classList.add('cn-filter-active');
+ } else {
+ el.classList.remove('cn-filter-active');
+ }
+ });
+ }
});
+
{{/if}}
{{/foreach}}
function sse_bs_init() {
- if(sessionStorage.getItem('notification_open') !== null || typeof sse_type !== 'undefined' ) {
- if(typeof sse_type === 'undefined')
+ // Check if 'notification_open' exists in sessionStorage or if sse_type is defined
+ if (sessionStorage.getItem('notification_open') !== null || typeof sse_type !== 'undefined') {
+ if (typeof sse_type === 'undefined') {
sse_type = sessionStorage.getItem('notification_open');
+ }
+
+ // Add the 'show' class to the appropriate element
+ let subNav = document.getElementById("nav-" + sse_type + "-sub");
+ if (subNav) {
+ subNav.classList.add('show');
+ }
- $("#nav-" + sse_type + "-sub").addClass('show');
+ // Call the sse_bs_notifications function
sse_bs_notifications(sse_type, true, false);
- }
- else {
+ } else {
+ // Call the sse_bs_counts function if conditions are not met
sse_bs_counts();
}
}
function sse_bs_counts() {
- if(sse_bs_active || sse_sys_only) {
+ if (sse_bs_active || sse_sys_only) {
return;
}
sse_bs_active = true;
- $.ajax({
- type: 'post',
- url: '/sse_bs',
- data: { sse_rmids }
- }).done( function(obj) {
+ // Use the fetch API to send the POST request with the data
+ fetch('/sse_bs', {
+ method: 'POST',
+ body: new URLSearchParams({sse_rmids: sse_rmids})
+ })
+ .then(response => response.json()) // Parse the JSON response
+ .then(obj => {
console.log(obj);
sse_bs_active = false;
sse_rmids = [];
sse_handleNotifications(obj, true, false);
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ sse_bs_active = false;
});
}
function sse_bs_notifications(e, replace, followup) {
-
- if(sse_bs_active || sse_sys_only) {
+ if (sse_bs_active || sse_sys_only) {
return;
}
let manual = false;
- if(typeof replace === 'undefined')
+ if (typeof replace === 'undefined') {
replace = e.data.replace;
+ }
- if(typeof followup === 'undefined')
+ if (typeof followup === 'undefined') {
followup = e.data.followup;
+ }
- if(typeof e === 'string') {
+ if (typeof e === 'string') {
sse_type = e;
- }
- else {
+ } else {
manual = true;
sse_offset = 0;
sse_type = e.target.dataset.sse_type;
}
- if(typeof sse_type === 'undefined')
+ if (typeof sse_type === 'undefined') {
return;
+ }
- if(followup || !manual || !$('#notification-link-' + sse_type).hasClass('collapsed')) {
+ if (followup || !manual || !document.getElementById('notification-link-' + sse_type).classList.contains('collapsed')) {
- if(sse_offset >= 0) {
- $("#nav-" + sse_type + "-loading").show();
+ if (sse_offset >= 0) {
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
}
sessionStorage.setItem('notification_open', sse_type);
- if(sse_offset !== -1 || replace) {
- var cn_val = (($('#cn-' + sse_type + '-input').length && sse_partial_result) ? $('#cn-' + sse_type + '-input').val().toString().toLowerCase() : '');
+ if (sse_offset !== -1 || replace) {
+ let cn_val = (document.getElementById('cn-' + sse_type + '-input') && sse_partial_result)
+ ? document.getElementById('cn-' + sse_type + '-input').value.toString().toLowerCase()
+ : '';
- $("#nav-" + sse_type + "-loading").show();
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
sse_bs_active = true;
- $.ajax({
- type: 'post',
- url: '/sse_bs/' + sse_type + '/' + sse_offset,
- nquery: encodeURIComponent(cn_val),
- data: { sse_rmids }
- }).done(function(obj) {
+ // Send POST request using fetch API
+ fetch('/sse_bs/' + sse_type + '/' + sse_offset, {
+ method: 'POST',
+ body: new URLSearchParams({
+ sse_rmids: sse_rmids,
+ nquery: encodeURIComponent(cn_val)
+ })
+ })
+ .then(response => response.json()) // Parse the JSON response
+ .then(obj => {
console.log('sse: bootstraping ' + sse_type);
console.log(obj);
sse_bs_active = false;
sse_rmids = [];
- $("#nav-" + sse_type + "-loading").hide();
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
sse_offset = obj[sse_type].offset;
sse_handleNotifications(obj, replace, followup);
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ sse_bs_active = false;
});
+ } else {
+ document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
}
- else {
- $("#nav-" + sse_type + "-loading").hide();
- }
- }
- else {
+ } else {
sessionStorage.removeItem('notification_open');
}
}
function sse_handleNotifications(obj, replace, followup) {
-
- // notice and info
-
- if(obj.notice) {
- $(obj.notice.notifications).each(function() {
- toast(this, 'danger');
+ // Notice and info notifications
+ if (obj.notice) {
+ obj.notice.notifications.forEach(notification => {
+ toast(notification, 'danger');
});
}
- if(obj.info) {
- $(obj.info.notifications).each(function(){
- toast(this, 'info');
+ if (obj.info) {
+ obj.info.notifications.forEach(notification => {
+ toast(notification, 'info');
});
}
@@ -325,218 +440,269 @@
let primary_notifications = ['dm', 'home', 'intros', 'register', 'notify', 'files'];
let secondary_notifications = ['network', 'forums', 'all_events', 'pubs'];
- let all_notifications = primary_notifications.concat(secondary_notifications);
+ let all_notifications = [...primary_notifications, ...secondary_notifications];
- all_notifications.forEach(function(type, index) {
- if(typeof obj[type] === typeof undefined)
- return true;
+ all_notifications.forEach(type => {
+ if (typeof obj[type] === 'undefined') {
+ return;
+ }
- var count = Number(obj[type].count);
+ let count = Number(obj[type].count);
- if(obj[type].count) {
- $('.' + type + '-button').fadeIn();
- if(replace || followup) {
- $('.' + type + '-update').html(count >= 100 ? '99+' : count);
- }
- else {
- count = count + Number($('.' + type + '-update').html().replace(/\++$/, ''));
- $('.' + type + '-update').html(count >= 100 ? '99+' : count);
+ // Show notifications and update count
+ let updateElement = document.querySelector('.' + type + '-update');
+ let buttonElement = document.querySelector('.' + type + '-button');
+ let subElement = document.getElementById('nav-' + type + '-sub');
+
+ if (count) {
+ if (buttonElement) buttonElement.style.display = 'block'; // Fade-in effect replaced by display block
+ if (replace || followup) {
+ updateElement.textContent = count >= 100 ? '99+' : count;
+ } else {
+ count = count + Number(updateElement.textContent.replace(/\++$/, ''));
+ updateElement.textContent = count >= 100 ? '99+' : count;
}
- }
- else {
- $('.' + type + '-update').html('0');
- $('#nav-' + type + '-sub').removeClass('show');
- $('.' + type + '-button').fadeOut(function() {
+ } else {
+ updateElement.textContent = '0';
+ if (subElement) subElement.classList.remove('show');
+ if (buttonElement) {
+ buttonElement.style.display = 'none'; // Fade-out effect replaced by display none
sse_setNotificationsStatus();
- });
+ }
}
- if(obj[type].notifications.length)
+
+ if (obj[type].notifications.length) {
sse_handleNotificationsItems(type, obj[type].notifications, replace, followup);
+ }
});
sse_setNotificationsStatus();
- // load more notifications if visible notifications count becomes low
- if(sse_type && sse_offset != -1 && $('#nav-' + sse_type + '-menu').children(':not(.tt-filter-active)').length < 15) {
- sse_bs_notifications(sse_type, false, true);
+ // Load more notifications if visible notifications count becomes low
+ if (sse_type && sse_offset !== -1) {
+ let menu = document.getElementById('nav-' + sse_type + '-menu');
+ if (menu && menu.children.length < 15) {
+ sse_bs_notifications(sse_type, false, true);
+ }
}
-
-
}
- function sse_handleNotificationsItems(notifyType, data, replace, followup) {
-
- let notifications_tpl = ((notifyType == 'forums') ? decodeURIComponent($("#nav-notifications-forums-template[rel=template]").html().replace('data-src', 'src')) : decodeURIComponent($("#nav-notifications-template[rel=template]").html().replace('data-src', 'src')));
- let notify_menu = $("#nav-" + notifyType + "-menu");
- let notify_loading = $("#nav-" + notifyType + "-loading");
- let notify_count = $("." + notifyType + "-update");
- if(replace && !followup) {
- notify_menu.html('');
- notify_loading.hide();
- }
+ function sse_handleNotificationsItems(notifyType, data, replace, followup) {
- $(data).each(function() {
+ // Get the template, adjust based on the notification type
+ let notifications_tpl = (notifyType === 'forums')
+ ? decodeURIComponent(document.querySelector("#nav-notifications-forums-template[rel=template]").innerHTML.replace('data-src', 'src'))
+ : decodeURIComponent(document.querySelector("#nav-notifications-template[rel=template]").innerHTML.replace('data-src', 'src'));
- // do not add a notification if it is already present
+ let notify_menu = document.getElementById("nav-" + notifyType + "-menu");
+ let notify_loading = document.getElementById("nav-" + notifyType + "-loading");
+ let notify_count = document.getElementsByClassName(notifyType + "-update");
- // TODO: this is questionable because at least in 'notify' notification type an item can have more than one notifications
- // e.g. one for the mention and one for the item itself.
- //if($('#nav-' + notifyType + '-menu .notification[data-b64mid=\'' + this.b64mid + '\']').length)
- // return true;
+ if (replace && !followup) {
+ notify_menu.innerHTML = ''; // Clear menu
+ notify_loading.style.display = 'none'; // Hide loading
+ }
- if(!replace && !followup && (this.thread_top && notifyType === 'network')) {
- $(document).trigger('hz:handleNetworkNotificationsItems', this);
+ data.forEach(notification => {
+ // Special handling for network notifications
+ if (!replace && !followup && notification.thread_top && notifyType === 'network') {
+ document.dispatchEvent(new CustomEvent('hz:handleNetworkNotificationsItems', { detail: notification }));
}
- let html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.addr,this.message,this.when,this.hclass,this.b64mid,this.notify_id,this.thread_top,this.unseen,this.private_forum, encodeURIComponent(this.mids), this.body);
- notify_menu.append(html);
+ // Prepare HTML using the template
+ let html = notifications_tpl.format(
+ notification.notify_link,
+ notification.photo,
+ notification.name,
+ notification.addr,
+ notification.message,
+ notification.when,
+ notification.hclass,
+ notification.b64mid,
+ notification.notify_id,
+ notification.thread_top,
+ notification.unseen,
+ notification.private_forum,
+ encodeURIComponent(notification.mids),
+ notification.body
+ );
+
+ // Append the new notification HTML to the menu
+ notify_menu.insertAdjacentHTML('beforeend', html);
});
- if(!replace && !followup) {
- $("#nav-" + notifyType + "-menu .notification").sort(function(a,b) {
- a = new Date(a.dataset.when);
- b = new Date(b.dataset.when);
- return a > b ? -1 : a < b ? 1 : 0;
- }).appendTo('#nav-' + notifyType + '-menu');
+ // Sort notifications by date
+ if (!replace && !followup) {
+ let notifications = Array.from(notify_menu.getElementsByClassName('notification'));
+ notifications.sort((a, b) => {
+ let dateA = new Date(a.dataset.when);
+ let dateB = new Date(b.dataset.when);
+ return dateA > dateB ? -1 : dateA < dateB ? 1 : 0;
+ });
+ notifications.forEach(notification => notify_menu.appendChild(notification));
}
- if($('#tt-' + notifyType + '-only').hasClass('active'))
- $('#nav-' + notifyType + '-menu [data-thread_top=false]').addClass('tt-filter-active');
-
- if($('#cn-' + notifyType + '-input').length) {
- let filter = $('#cn-' + notifyType + '-input').val().toString().toLowerCase();
- if(filter) {
- filter = filter.indexOf('%') == 0 ? filter.substring(1) : filter;
-
- $('#nav-' + notifyType + '-menu .notification').each(function(i, el) {
- let cn = $(el).data('contact_name').toString().toLowerCase();
- let ca = $(el).data('contact_addr').toString().toLowerCase();
- if(cn.indexOf(filter) === -1 && ca.indexOf(filter) === -1)
- $(el).addClass('cn-filter-active');
- else
- $(el).removeClass('cn-filter-active');
+ // Filter thread_top notifications if the filter is active
+ if (document.getElementById('tt-' + notifyType + '-only').classList.contains('active')) {
+ let notifications = notify_menu.querySelectorAll('[data-thread_top="false"]');
+ notifications.forEach(notification => notification.classList.add('tt-filter-active'));
+ }
+
+ // Filter notifications based on the input field
+ let filterInput = document.getElementById('cn-' + notifyType + '-input');
+ if (filterInput) {
+ let filter = filterInput.value.toString().toLowerCase();
+ if (filter) {
+ if (filter.indexOf('%') === 0) filter = filter.substring(1); // Remove the percent if it exists
+ let notifications = notify_menu.querySelectorAll('.notification');
+ notifications.forEach(notification => {
+ let cn = notification.dataset.contactName.toString().toLowerCase();
+ let ca = notification.dataset.contactAddr.toString().toLowerCase();
+ if (cn.indexOf(filter) === -1 && ca.indexOf(filter) === -1) {
+ notification.classList.add('cn-filter-active');
+ } else {
+ notification.classList.remove('cn-filter-active');
+ }
});
}
}
+ // Update relative time for notifications
updateRelativeTime('.autotime-narrow');
}
+
function sse_updateNotifications(type, mid) {
- /*
- if(type === 'pubs')
+ // Skip processing if the type is 'notify' and the conditions don't match
+ if (type === 'notify' && (mid !== bParam_mid || sse_type !== 'notify')) {
return true;
- */
- if(type === 'notify' && (mid !== bParam_mid || sse_type !== 'notify'))
- return true;
- /*
- var count = Number($('.' + type + '-update').html());
+ }
- count--;
+ // Find the notification element based on its 'data-b64mid' attribute
+ let notification = document.querySelector(`#nav-${type}-menu .notification[data-b64mid='${mid}']`);
- if(count < 1) {
- $('.' + type + '-update').html(count);
- $('.' + type + '-button').fadeOut(function() {
- sse_setNotificationsStatus();
+ if (notification) {
+ // Fade out the notification by adjusting its opacity
+ notification.style.transition = 'opacity 0.5s';
+ notification.style.opacity = 0;
+
+ // After the transition ends, remove the notification element from the DOM
+ notification.addEventListener('transitionend', function () {
+ notification.remove();
});
}
- else {
- $('.' + type + '-update').html(count);
- }
- */
-
- $('#nav-' + type + '-menu .notification[data-b64mid=\'' + mid + '\']').fadeOut(function() {
- this.remove();
- });
-
}
+
function sse_setNotificationsStatus(data) {
- var primary_notifications = ['dm', 'home', 'intros', 'register', 'notify', 'files'];
- var secondary_notifications = ['network', 'forums', 'all_events', 'pubs'];
- var all_notifications = primary_notifications.concat(secondary_notifications);
+ let primary_notifications = ['dm', 'home', 'intros', 'register', 'notify', 'files'];
+ let secondary_notifications = ['network', 'forums', 'all_events', 'pubs'];
+ let all_notifications = primary_notifications.concat(secondary_notifications);
- var primary_available = false;
- var any_available = false;
+ let primary_available = false;
+ let any_available = false;
- all_notifications.forEach(function(type, index) {
- if($('.' + type + '-button').css('display') == 'block') {
+ // Loop through all notifications and check their visibility
+ all_notifications.forEach(function (type) {
+ let button = document.querySelector(`.${type}-button`);
+ if (button && getComputedStyle(button).display === 'block') {
any_available = true;
- if(primary_notifications.indexOf(type) > -1)
+ if (primary_notifications.indexOf(type) > -1) {
primary_available = true;
+ }
}
});
- if(primary_available) {
- $('.notifications-btn-icon').removeClass('bi-exclamation-circle');
- $('.notifications-btn-icon').addClass('bi-exclamation-triangle');
- }
- else {
- $('.notifications-btn-icon').removeClass('bi-exclamation-triangle');
- $('.notifications-btn-icon').addClass('bi-exclamation-circle');
+ // Update notification button icon based on the primary notification availability
+ let notificationIcon = document.querySelector('.notifications-btn-icon');
+ if (primary_available) {
+ notificationIcon.classList.remove('bi-exclamation-circle');
+ notificationIcon.classList.add('bi-exclamation-triangle');
+ } else {
+ notificationIcon.classList.remove('bi-exclamation-triangle');
+ notificationIcon.classList.add('bi-exclamation-circle');
}
- if(any_available) {
- $('.notifications-btn').css('opacity', 1);
- $('#no_notifications').hide();
- $('#notifications').show();
- }
- else {
- $('.notifications-btn').css('opacity', 0.5);
- $('#navbar-collapse-1').removeClass('show');
- $('#no_notifications').show();
- $('#notifications').hide();
+ // Update visibility of notification button and sections
+ let notificationsBtn = document.querySelector('.notifications-btn');
+ let noNotifications = document.querySelector('#no_notifications');
+ let notifications = document.querySelector('#notifications');
+ let navbarCollapse = document.querySelector('#navbar-collapse-1');
+
+ if (any_available) {
+ notificationsBtn.style.opacity = 1;
+ noNotifications.style.display = 'none';
+ notifications.style.display = 'block';
+ } else {
+ notificationsBtn.style.opacity = 0.5;
+ if (navbarCollapse) navbarCollapse.classList.remove('show');
+ noNotifications.style.display = 'block';
+ notifications.style.display = 'none';
}
- if (typeof data !== typeof undefined) {
- data.forEach(function(nmid, index) {
-
+ // Handle specific notifications if 'data' is provided
+ if (typeof data !== 'undefined') {
+ data.forEach(function (nmid) {
sse_rmids.push(nmid);
- if($('.notification[data-b64mid=\'' + nmid + '\']').length) {
- $('.notification[data-b64mid=\'' + nmid + '\']').each(function() {
- var n = this.parentElement.id.split('-');
- return sse_updateNotifications(n[1], nmid);
- });
+ // Handle regular notifications
+ let notification = document.querySelector(`.notification[data-b64mid='${nmid}']`);
+ if (notification) {
+ let parentId = notification.parentElement.id.split('-')[1];
+ sse_updateNotifications(parentId, nmid);
}
- // special handling for forum notifications
- $('.notification-forum').filter(function() {
- var fmids = decodeURIComponent($(this).data('b64mids'));
- var n = this.parentElement.id.split('-');
- if(fmids.indexOf(nmid) > -1) {
- var fcount = Number($('.' + n[1] + '-update').html());
+ // Special handling for forum notifications
+ let forumNotifications = document.querySelectorAll('.notification-forum');
+ forumNotifications.forEach(function (forumNotification) {
+ let fmids = decodeURIComponent(forumNotification.dataset.b64mids);
+ let parentId = forumNotification.parentElement.id.split('-')[1];
+
+ if (fmids.indexOf(nmid) > -1) {
+ let updateElem = document.querySelector(`.${parentId}-update`);
+ let fcount = Number(updateElem.innerText);
fcount--;
- $('.' + n[1] + '-update').html(fcount);
- if(fcount < 1) {
- $('.' + n[1] + '-button').fadeOut();
- $('#nav-' + n[1] + '-sub').removeClass('show');
+ updateElem.innerText = fcount;
+
+ if (fcount < 1) {
+ let button = document.querySelector(`.${parentId}-button`);
+ button.style.display = 'none';
+ let subMenu = document.querySelector(`#nav-${parentId}-sub`);
+ if (subMenu) subMenu.classList.remove('show');
}
- var count = Number($(this).find('.bg-secondary').html());
+
+ let countElem = forumNotification.querySelector('.bg-secondary');
+ let count = Number(countElem.innerText);
count--;
- $(this).find('.bg-secondary').html(count);
- if(count < 1)
- $(this).remove();
+ countElem.innerText = count;
+
+ if (count < 1) {
+ forumNotification.remove();
+ }
}
});
});
}
-
}
function sse_fallback() {
- $.get('/sse', function(obj) {
- if(! obj)
- return;
+ fetch('/sse')
+ .then(response => response.json())
+ .then(obj => {
+ if (!obj) return;
- console.log('sse fallback');
- console.log(obj);
+ console.log('sse fallback');
+ console.log(obj);
- sse_handleNotifications(obj, false, false);
- });
+ sse_handleNotifications(obj, false, false);
+ })
+ .catch(error => {
+ console.error('Error fetching SSE data:', error);
+ });
}
+
</script>
{{if !$sys_only}}