mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
properly implement forum notifications
This commit is contained in:
@@ -135,7 +135,6 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
|
||||
$status_editor = '';
|
||||
|
||||
|
||||
if (Apps::system_app_installed(local_channel(), 'Affinity Tool')) {
|
||||
$affinity_locked = intval(get_pconfig(local_channel(), 'affinity', 'lock', 1));
|
||||
if ($affinity_locked) {
|
||||
@@ -273,18 +272,6 @@ class Network extends \Zotlabs\Web\Controller {
|
||||
// This is for nouveau view cid queries (not a public forum)
|
||||
$sql_extra = " AND author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ";
|
||||
}
|
||||
elseif($pf && $unseen && $nouveau) {
|
||||
|
||||
$vnotify = get_pconfig(local_channel(), 'system', 'vnotify');
|
||||
$likes_sql = '';
|
||||
if (!($vnotify & VNOTIFY_LIKE)) {
|
||||
$likes_sql = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
|
||||
// This is for nouveau view public forum cid queries (if a forum notification is clicked)
|
||||
$sql_extra = " AND item.parent IN (SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal) AND item_unseen = 1 AND verb != 'Announce' $likes_sql ";
|
||||
|
||||
}
|
||||
else {
|
||||
// This is for threaded view cid queries (e.g. if a forum is selected from the forum filter)
|
||||
$sql_extra = " AND item.parent IN (SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal) ";
|
||||
|
||||
@@ -91,8 +91,14 @@ class Sse_bs extends Controller {
|
||||
default:
|
||||
}
|
||||
|
||||
$selected_forum_id = null;
|
||||
if (str_starts_with(argv(1), 'forum_')) {
|
||||
$selected_forum_id = argv(1);
|
||||
$f = 'bs_forums';
|
||||
}
|
||||
|
||||
if(self::$offset && $f) {
|
||||
$result = self::$f(true);
|
||||
$result = self::$f($selected_forum_id ?? true);
|
||||
json_return_and_die($result);
|
||||
}
|
||||
|
||||
@@ -102,7 +108,7 @@ class Sse_bs extends Controller {
|
||||
self::bs_home($home),
|
||||
self::bs_notify(),
|
||||
self::bs_intros(),
|
||||
self::bs_forums(),
|
||||
self::bs_forums($selected_forum_id),
|
||||
self::bs_pubs($pubs),
|
||||
self::bs_files(),
|
||||
self::bs_all_events(),
|
||||
@@ -610,69 +616,94 @@ class Sse_bs extends Controller {
|
||||
|
||||
}
|
||||
|
||||
function bs_forums() {
|
||||
function bs_forums($selected_forum_id) {
|
||||
|
||||
$result['forums']['notifications'] = [];
|
||||
$result['forums']['count'] = 0;
|
||||
$result['forums']['offset'] = -1;
|
||||
|
||||
if(! self::$uid)
|
||||
return $result;
|
||||
|
||||
if(! (self::$vnotify & VNOTIFY_FORUMS))
|
||||
if(!self::$uid || !(self::$vnotify & VNOTIFY_FORUMS)) {
|
||||
$result['forum']['notifications'] = [];
|
||||
$result['forum']['count'] = 0;
|
||||
$result['forum']['offset'] = -1;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$forums = get_forum_channels(self::$uid);
|
||||
|
||||
if($forums) {
|
||||
$item_normal = item_normal();
|
||||
$p_sql = '';
|
||||
|
||||
$sql_extra = '';
|
||||
if(! (self::$vnotify & VNOTIFY_LIKE))
|
||||
$sql_extra = " AND verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
|
||||
$fcount = count($forums);
|
||||
$i = 0;
|
||||
|
||||
for($x = 0; $x < $fcount; $x ++) {
|
||||
|
||||
$r = q("select count(*) as total from item
|
||||
where uid = %d and (owner_xchan = '%s' or author_xchan = '%s') and author_xchan != '%s' and verb != 'Announce' and item_unseen = 1 $sql_extra $item_normal",
|
||||
$forum_id = 'forum_' . $forums[$x]['abook_id'];
|
||||
|
||||
$result[$forum_id]['notifications'] = [];
|
||||
$result[$forum_id]['count'] = 0;
|
||||
|
||||
$limit = intval(self::$limit);
|
||||
$offset = self::$offset;
|
||||
|
||||
$sql_extra = '';
|
||||
if (!(self::$vnotify & VNOTIFY_LIKE)) {
|
||||
$sql_extra = " AND item.verb NOT IN ('Like', 'Dislike', '" . dbesc(ACTIVITY_LIKE) . "', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
elseif (!feature_enabled(self::$uid, 'dislike')) {
|
||||
$sql_extra = " AND item.verb NOT IN ('Dislike', '" . dbesc(ACTIVITY_DISLIKE) . "') ";
|
||||
}
|
||||
|
||||
$item_normal = item_normal();
|
||||
|
||||
// Filter internal follow activities and strerams add/remove activities
|
||||
$item_normal .= " AND item.verb NOT IN ('Add', 'Remove', 'Follow', 'Ignore', '" . dbesc(ACTIVITY_FOLLOW) . "') ";
|
||||
|
||||
if ($forum_id === $selected_forum_id) {
|
||||
$items = q("SELECT item.*, tp.uuid AS thr_parent_uuid FROM item
|
||||
LEFT JOIN item tp ON item.thr_parent = tp.mid AND item.uid = tp.uid
|
||||
WHERE item.uid = %d
|
||||
AND item.created <= '%s'
|
||||
AND item.owner_xchan = '%s'
|
||||
AND item.item_unseen = 1 AND item.item_wall = 0 AND item.item_private IN (0, 1)
|
||||
AND item.obj_type NOT IN ('Document', 'Video', 'Audio', 'Image')
|
||||
AND NOT (item.verb = 'Announce' AND item.item_thread_top = 1) -- only show the announce activity and not the resulting item
|
||||
AND NOT item.author_xchan = '%s'
|
||||
$item_normal
|
||||
$sql_extra
|
||||
ORDER BY item.created DESC LIMIT $limit OFFSET $offset",
|
||||
intval(self::$uid),
|
||||
dbescdate($_SESSION['sse_loadtime']),
|
||||
dbescdate($forums[$x]['xchan_hash']),
|
||||
dbesc(self::$ob_hash)
|
||||
);
|
||||
|
||||
if ($items) {
|
||||
$result[$forum_id]['offset'] = ((count($items) == $limit) ? intval($offset + $limit) : -1);
|
||||
xchan_query($items);
|
||||
foreach($items as $item) {
|
||||
$parsed = Enotify::format($item);
|
||||
if($parsed) {
|
||||
$result[$forum_id]['notifications'][] = $parsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$result[$forum_id]['offset'] = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$r = q("SELECT id FROM item
|
||||
WHERE uid = %d and item_unseen = 1 AND item_wall = 0 AND item_private IN (0, 1)
|
||||
AND obj_type NOT IN ('Document', 'Video', 'Audio', 'Image')
|
||||
AND author_xchan != '%s'
|
||||
AND item.owner_xchan = '%s'
|
||||
$item_normal
|
||||
$sql_extra LIMIT 100",
|
||||
intval(self::$uid),
|
||||
dbesc($forums[$x]['xchan_hash']),
|
||||
dbesc($forums[$x]['xchan_hash']),
|
||||
dbesc(self::$ob_hash)
|
||||
dbesc(self::$ob_hash),
|
||||
dbesc($forums[$x]['xchan_hash'])
|
||||
);
|
||||
|
||||
if($r[0]['total']) {
|
||||
|
||||
$forums[$x]['notify_link'] = z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id'];
|
||||
$forums[$x]['name'] = $forums[$x]['xchan_name'];
|
||||
$forums[$x]['addr'] = $forums[$x]['xchan_addr'] ?? $forums[$x]['xchan_url'];
|
||||
$forums[$x]['url'] = $forums[$x]['xchan_url'];
|
||||
$forums[$x]['photo'] = $forums[$x]['xchan_photo_s'];
|
||||
$forums[$x]['unseen'] = $r[0]['total'];
|
||||
$forums[$x]['private_forum'] = ((isset($forums[$x]['private_forum']) && $forums[$x]['private_forum']) ? 'lock' : '');
|
||||
$forums[$x]['message'] = ((isset($forums[$x]['private_forum']) && $forums[$x]['private_forum']) ? t('Private forum') : t('Public forum'));
|
||||
|
||||
unset($forums[$x]['abook_id']);
|
||||
unset($forums[$x]['xchan_hash']);
|
||||
unset($forums[$x]['xchan_name']);
|
||||
unset($forums[$x]['xchan_url']);
|
||||
unset($forums[$x]['xchan_photo_s']);
|
||||
|
||||
$i = $i + $r[0]['total'];
|
||||
|
||||
}
|
||||
else {
|
||||
unset($forums[$x]);
|
||||
if ($r) {
|
||||
$result[$forum_id]['count'] = count($r);
|
||||
}
|
||||
}
|
||||
|
||||
$result['forums']['count'] = $i;
|
||||
$result['forums']['notifications'] = array_values($forums);
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -12,7 +12,6 @@ class Notifications {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
$channel = \App::get_channel();
|
||||
$notifications = [];
|
||||
|
||||
if(local_channel()) {
|
||||
@@ -35,7 +34,6 @@ class Notifications {
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
$notifications[] = [
|
||||
'type' => 'home',
|
||||
'icon' => 'house',
|
||||
@@ -43,7 +41,7 @@ class Notifications {
|
||||
'label' => t('Channel'),
|
||||
'title' => t('Unseen channel activity'),
|
||||
'viewall' => [
|
||||
'url' => 'channel/' . $channel['channel_address'],
|
||||
'url' => 'channel',
|
||||
'label' => t('Channel stream')
|
||||
],
|
||||
'markall' => [
|
||||
@@ -124,16 +122,17 @@ class Notifications {
|
||||
]
|
||||
];
|
||||
|
||||
$notifications[] = [
|
||||
'type' => 'forums',
|
||||
'icon' => 'chat-quote',
|
||||
'severity' => 'secondary',
|
||||
'label' => t('Forums'),
|
||||
'title' => t('Unseen forums activity'),
|
||||
'filter' => [
|
||||
'name_label' => t('Filter by name or address')
|
||||
]
|
||||
];
|
||||
$forums = get_forum_channels(local_channel());
|
||||
foreach($forums as $forum) {
|
||||
$notifications[] = [
|
||||
'type' => 'forum_' . $forum['abook_id'],
|
||||
'icon' => 'chat-quote',
|
||||
'severity' => 'secondary',
|
||||
'label' => $forum['xchan_name'],
|
||||
'title' => t('Unseen forum activity')
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(local_channel() && is_site_admin()) {
|
||||
@@ -157,11 +156,6 @@ class Notifications {
|
||||
'url' => 'pubstream',
|
||||
'label' => t('Public stream')
|
||||
],
|
||||
/*
|
||||
'markall' => [
|
||||
'label' => t('Mark all notifications seen')
|
||||
],
|
||||
*/
|
||||
'filter' => [
|
||||
'posts_label' => t('Conversation starters'),
|
||||
'name_label' => t('Filter by name or address')
|
||||
@@ -169,16 +163,13 @@ class Notifications {
|
||||
];
|
||||
}
|
||||
|
||||
$o = replace_macros(get_markup_template('notifications_widget.tpl'), [
|
||||
return replace_macros(get_markup_template('notifications_widget.tpl'), [
|
||||
'$notifications' => $notifications,
|
||||
'$no_notifications' => t('Sorry, you have got no notifications at the moment'),
|
||||
'$loading' => t('Loading'),
|
||||
'$sys_only' => empty($arr['sys_only']) ? 0 : 1
|
||||
|
||||
]);
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
boot.php
2
boot.php
@@ -70,7 +70,7 @@ require_once('include/security.php');
|
||||
|
||||
|
||||
define('PLATFORM_NAME', 'hubzilla');
|
||||
define('STD_VERSION', '10.5.8');
|
||||
define('STD_VERSION', '10.5.9');
|
||||
define('ZOT_REVISION', '6.0');
|
||||
|
||||
define('DB_UPDATE_VERSION', 1264);
|
||||
|
||||
@@ -135,7 +135,6 @@
|
||||
|
||||
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';
|
||||
}
|
||||
@@ -297,7 +296,7 @@
|
||||
});
|
||||
|
||||
document.addEventListener('hz:sse_setNotificationsStatus', function(e) {
|
||||
sse_setNotificationsStatus(e.detail);
|
||||
sse_setNotificationsStatus(e.detail, null);
|
||||
});
|
||||
|
||||
document.addEventListener('hz:sse_bs_init', function() {
|
||||
@@ -414,7 +413,6 @@
|
||||
sse_bs_active = false;
|
||||
sse_rmids = [];
|
||||
document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
|
||||
sse_offset = obj[sse_type].offset;
|
||||
sse_handleNotifications(obj, replace, followup);
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -430,6 +428,7 @@
|
||||
}
|
||||
|
||||
function sse_handleNotifications(obj, replace, followup) {
|
||||
|
||||
// Notice and info notifications
|
||||
if (obj.notice) {
|
||||
obj.notice.notifications.forEach(notification => {
|
||||
@@ -447,9 +446,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
let primary_notifications = ['dm', 'home', 'intros', 'register', 'notify', 'files'];
|
||||
let secondary_notifications = ['network', 'forums', 'all_events', 'pubs'];
|
||||
let all_notifications = [...primary_notifications, ...secondary_notifications];
|
||||
let all_notifications = Object.keys(obj);
|
||||
|
||||
all_notifications.forEach(type => {
|
||||
if (typeof obj[type] === 'undefined') {
|
||||
@@ -476,7 +473,7 @@
|
||||
if (subElement) subElement.classList.remove('show');
|
||||
if (buttonElement) {
|
||||
buttonElement.style.display = 'none'; // Fade-out effect replaced by display none
|
||||
sse_setNotificationsStatus();
|
||||
sse_setNotificationsStatus(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,24 +482,23 @@
|
||||
}
|
||||
});
|
||||
|
||||
sse_setNotificationsStatus();
|
||||
sse_setNotificationsStatus(null, all_notifications);
|
||||
|
||||
// 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);
|
||||
if (typeof obj[sse_type] !== 'undefined') {
|
||||
sse_offset = obj[sse_type].offset;
|
||||
|
||||
// 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) {
|
||||
|
||||
// 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'));
|
||||
|
||||
let notifications_tpl = decodeURIComponent(document.querySelector("#nav-notifications-template[rel=template]").innerHTML.replace('data-src', 'src'));
|
||||
let notify_menu = document.getElementById("nav-" + notifyType + "-menu");
|
||||
let notify_loading = document.getElementById("nav-" + notifyType + "-loading");
|
||||
let notify_count = document.getElementsByClassName(notifyType + "-update");
|
||||
@@ -598,10 +594,14 @@
|
||||
}
|
||||
|
||||
|
||||
function sse_setNotificationsStatus(data) {
|
||||
function sse_setNotificationsStatus(data, all_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);
|
||||
|
||||
if (!all_notifications) {
|
||||
all_notifications = primary_notifications.concat(secondary_notifications);
|
||||
}
|
||||
|
||||
let primary_available = false;
|
||||
let any_available = false;
|
||||
@@ -650,46 +650,17 @@
|
||||
}
|
||||
|
||||
// Handle specific notifications if 'data' is provided
|
||||
if (typeof data !== 'undefined') {
|
||||
if (data) {
|
||||
data.forEach(function (nmid) {
|
||||
sse_rmids.push(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
|
||||
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--;
|
||||
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');
|
||||
}
|
||||
|
||||
let countElem = forumNotification.querySelector('.bg-secondary');
|
||||
let count = Number(countElem.innerText);
|
||||
count--;
|
||||
countElem.innerText = count;
|
||||
|
||||
if (count < 1) {
|
||||
forumNotification.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -731,15 +702,6 @@
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div id="nav-notifications-forums-template" rel="template" class="d-none">
|
||||
<a class="list-group-item list-group-item-action justify-content-between align-items-center d-flex notification notification-forum" href="{0}" title="{4} - {3}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}" data-b64mids='{12}'>
|
||||
<div>
|
||||
<img class="menu-img-1" data-src="{1}" loading="lazy">
|
||||
<span>{2}</span>
|
||||
</div>
|
||||
<span class="badge bg-secondary">{10}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div id="notifications" class="border border-top-0 rounded navbar-nav collapse">
|
||||
{{foreach $notifications as $notification}}
|
||||
<div class="rounded-top rounded-bottom border border-start-0 border-end-0 border-bottom-0 list-group list-group-flush collapse {{$notification.type}}-button">
|
||||
|
||||
Reference in New Issue
Block a user