Skip to content
Snippets Groups Projects
Commit 3020fd22 authored by Jay Friendly's avatar Jay Friendly
Browse files

Issue #2947739 by Jaypan: Integrating private message notification block with Node jS

parent 4d45fddd
No related branches found
No related tags found
No related merge requests found
......@@ -49,7 +49,9 @@ Drupal.PrivateMessageInbox.updateInbox = {};
success:function (data) {
loadingNew = false;
triggerCommands(data);
window.setTimeout(updateInbox, updateInterval);
if (updateInterval) {
window.setTimeout(updateInbox, updateInterval);
}
}
});
}
......
......@@ -6,6 +6,8 @@
/*global jQuery, Drupal, drupalSettings, window*/
/*jslint white:true, this, browser:true*/
Drupal.PrivateMessageNotificationBlock = {};
(function ($, Drupal, drupalSettings, window) {
"use strict";
......@@ -41,7 +43,7 @@
/**
* Retrieve the new unread thread count from the server using AJAX.
*/
function checkCount() {
function getUnreadThreadCount() {
if (!checkingCount) {
checkingCount = true;
......@@ -51,12 +53,18 @@
triggerCommands(data);
checkingCount = false;
window.setTimeout(checkCount, refreshRate);
if (refreshRate) {
window.setTimeout(getUnreadThreadCount, refreshRate);
}
}
});
}
}
Drupal.PrivateMessageNotificationBlock.getUnreadThreadCount = function () {
getUnreadThreadCount();
};
/**
* Initializes the script.
*/
......@@ -64,11 +72,12 @@
if (!initialized) {
initialized = true;
notificationWrapper = $(".private-message-notification-wrapper");
if (drupalSettings.privateMessageNotificationBlock.ajaxRefreshRate) {
notificationWrapper = $(".private-message-notification-wrapper");
refreshRate = drupalSettings.privateMessageNotificationBlock.ajaxRefreshRate * 1000;
if (refreshRate) {
window.setTimeout(checkCount, refreshRate);
window.setTimeout(getUnreadThreadCount, refreshRate);
}
}
}
......
......@@ -10,25 +10,26 @@
"use strict";
var initialized, messageSocket, inboxSocket;
var initialized, threadSocket, inboxSocket, notificationSocket;
function init() {
// Only initialize once.
if (!initialized) {
initialized = true;
// Connect to the Nodejs server.
messageSocket = io(drupalSettings.privateMessageNodejs.nodejsUrl + "/thread");
inboxSocket = io(drupalSettings.privateMessageNodejs.nodejsUrl + "/pm_inbox");
// Listen for a connection to the remote server.
messageSocket.on('connect', function () {
/********** Begin thread handling **********/
threadSocket = io(drupalSettings.privateMessageNodejs.nodejsUrl + "/pm_thread");
threadSocket.on('connect', function () {
// Enter for the room for this thread.
messageSocket.emit('room', drupalSettings.privateMessageThread.threadId);
threadSocket.emit('thread', drupalSettings.privateMessageThread.threadId);
});
// Listen for an emission informing of a new private message in the
// thread.
messageSocket.on("new private message", function () {
threadSocket.on("new private message", function () {
// Fetch new messages from the server.
Drupal.PrivateMessages.getNewMessages();
});
......@@ -37,39 +38,80 @@
Drupal.PrivateMessages.threadChange.privateMessageNodejs = {
threadLoaded: function (threadId) {
// Join the room for the new thread.
messageSocket.emit('room', threadId);
threadSocket.emit('thread', threadId);
}
};
// Listen for a connection to the remote server.
inboxSocket.on('connect', function () {
// Enter the room for this user.
inboxSocket.emit('room', drupalSettings.user.uid);
});
/********** Begin inbox handling **********/
// Listen for an emission informing of thread update for a thread the user
// belongs to.
inboxSocket.on("update pm inbox", function () {
// Fetch new messages from the server.
Drupal.PrivateMessageInbox.updateInbox();
});
if (Drupal.PrivateMessageInbox) {
}
inboxSocket = io(drupalSettings.privateMessageNodejs.nodejsUrl + "/pm_inbox");
Drupal.AjaxCommands.prototype.privateMessageNodejsTriggerNewMessages = function () {
messageSocket.emit("new private message", drupalSettings.privateMessageThread.threadId);
};
// Listen for a connection to the remote server.
inboxSocket.on('connect', function () {
// Enter the room for this user.
inboxSocket.emit('user', drupalSettings.user.uid);
});
Drupal.AjaxCommands.prototype.privateMessageNodejsTriggerInboxUpdateCommand = function (ajax, response) {
// Listen for an emission informing of thread update for a thread the user
// belongs to.
inboxSocket.on("update pm inbox", function () {
// Fetch new messages from the server.
Drupal.PrivateMessageInbox.updateInbox();
});
}
// For jSlint compatibility.
ajax = ajax;
/********** Begin notification handling **********/
$.each(response.uids, function (index) {
inboxSocket.emit("update pm inbox", response.uids[index]);
});
};
if (Drupal.PrivateMessageNotificationBlock) {
notificationSocket = io(drupalSettings.privateMessageNodejs.nodejsUrl + "/pm_notifications");
// Listen for a connection to the remote server.
notificationSocket.on('connect', function () {
// Enter the room for this user.
notificationSocket.emit('user', drupalSettings.user.uid);
});
// Listen for an emission informing of thread update for a thread the user
// belongs to.
notificationSocket.on("update pm unread thread count", function () {
// Fetch unread thread count from the server.
Drupal.PrivateMessageNotificationBlock.getUnreadThreadCount();
});
}
/********** Begin ajax command callbacks handling **********/
Drupal.AjaxCommands.prototype.privateMessageNodejsTriggerNewMessages = function () {
threadSocket.emit("new private message", drupalSettings.privateMessageThread.threadId);
};
Drupal.AjaxCommands.prototype.privateMessageNodejsTriggerInboxUpdateCommand = function (ajax, response) {
// For jSlint compatibility.
ajax = ajax;
if (Drupal.PrivateMessageInbox) {
$.each(response.uids, function (index) {
inboxSocket.emit("update pm inbox", response.uids[index]);
});
}
};
Drupal.AjaxCommands.prototype.privateMessageNodejsTriggerUnreadThreadCountUpdateCommand = function (ajax, response) {
// For jSlint compatibility.
ajax = ajax;
if (Drupal.PrivateMessageNotificationBlock) {
$.each(response.uids, function (index) {
notificationSocket.emit("update pm unread thread count", response.uids[index]);
});
}
};
}
}
Drupal.behaviors.privateMessageNodejs = {
......
......@@ -15,31 +15,22 @@
// The private message thread namespace. This namespace will be used to
// emit triggers that update private messages with new messages.
var threadChannel = io.of('/thread');
var threadChannel = io.of('/pm_thread');
threadChannel.on('connection', function (socket) {
/**
* A user's thread ID. This will be used for the room IDs.
*
* @var int
*/
var threadId;
console.log('user connected to thread namespace');
console.log('user connected to pm_thread namespace');
// Each private message thread will have its own room. This ensures that
// emissions only go to other users in the room, and not across all private
// message users everywhere.
socket.on('room', function (room) {
// Set the thread ID, so that it can be used in other callbacks.
threadId = room;
console.log("joining thread room: " + room);
socket.on('thread', function (threadId) {
console.log("joining thread: " + threadId);
// Join the room for the given thread.
socket.join(room);
socket.join(threadId);
});
// Triggered when a new private message has been added to a thread.
socket.on('new private message', function () {
socket.on('new private message', function (threadId) {
console.log("Sending private message to thread: " + threadId);
// Tell all users in the room that a new private message is ready to be
// fetched.
......@@ -51,31 +42,59 @@
});
});
// The private message thread namespace. This namespace will be used to
// emit triggers that update private messages with new messages.
// The private message inbox namespace. This namespace will be used to
// emit triggers that update the private message inbox.
var inboxChannel = io.of('/pm_inbox');
inboxChannel.on('connection', function (socket) {
console.log('user connected to pm_inbox namespace');
// Each user will have their own 'room'. This is so that updates to an
// individual user's inbox can happen, rather than having all users update
// their inbox.
socket.on('user', function (uid) {
console.log("joining pm inbox for user: " + uid);
// Join the room for the given user.
socket.join(uid);
});
// Triggered when a thread a user is a member of has been updated.
socket.on('update pm inbox', function (uid) {
console.log("triggering PM Inbox update for user: " + uid);
// Tell the users inbox to update.
inboxChannel.to(uid).emit('update pm inbox');
});
socket.on('disconnect', function () {
console.log('user disconnected from pm_inbox namespace');
});
});
// The private message notification namespace. This namespace will be used to
// emit a trigger to update the unread thread count.
var notficationBlockChannel = io.of('/pm_notifications');
notficationBlockChannel.on('connection', function (socket) {
console.log('user connected to pm_notifications namespace');
// Each private message thread will have its own room. This ensures that
// emissions only go to other users in the room, and not across all private
// message users everywhere.
socket.on('room', function (room) {
console.log("joining pm inbox room: " + room);
// Join the room for the given thread.
socket.join(room);
socket.on('user', function (user) {
console.log("joining pm thread count notification for user: " + user);
// Join the room for the given user.
socket.join(user);
});
// Triggered when a thread a user is a member of has been updated.
socket.on('update pm inbox', function (userId) {
console.log("triggering PM Inbox update for user: " + userId);
socket.on('update pm unread thread count', function (uid) {
console.log("triggering PM Notification update for user: " + uid);
// Tell the users inbox to update.
inboxChannel.to(userId).emit('update pm inbox');
notficationBlockChannel.to(uid).emit('update pm unread thread count');
});
socket.on('disconnect', function () {
console.log('user disconnected from pm_inbox namespace');
console.log('user disconnected from pm_notifications namespace');
});
});
......
......@@ -8,4 +8,3 @@ socket.io:
- core/jquery.once
- core/drupalSettings
- private_message/private_message_thread
- private_message/inbox_block
......@@ -36,12 +36,18 @@ function private_message_nodejs_form_entity_view_display_edit_form_alter(array &
* Alter block settings forms.
*/
function private_message_nodejs_form_block_form_alter(array &$form, FormStateInterface $formState) {
// Only act on the private message inbox block settings.
// Act on the private message inbox block settings.
if ($formState->getFormObject()->getEntity()->getPluginId() == 'private_message_inbox_block') {
// Set the ajax refresh rate to be hidden, as refreshing of the inbox will
// happen using nodejs.
$form['settings']['ajax_refresh_rate']['#access'] = FALSE;
}
// Act on the private message notification block settings.
elseif ($formState->getFormObject()->getEntity()->getPluginId() == 'private_message_notification_block') {
// Set the ajax refresh rate to be hidden, as refreshing of the inbox will
// happen using nodejs.
$form['settings']['ajax_refresh_rate']['#access'] = FALSE;
}
}
/**
......@@ -78,7 +84,7 @@ function private_message_nodejs_block_view_private_message_inbox_block_alter(arr
/**
* Custom prerender callback for the private message inbox block.
*
* Disables polling in the privat emessage inbox, as it is handled instead by
* Disables polling in the private message inbox, as it is handled instead by
* nodejs.
*/
function private_message_nodejs_block_view_private_message_inbox_block_pre_render($build) {
......@@ -86,3 +92,22 @@ function private_message_nodejs_block_view_private_message_inbox_block_pre_rende
return $build;
}
/**
* Implements hook_block_view_BASE_BLOCK_ID_alter().
*/
function private_message_nodejs_block_view_private_message_notification_block_alter(array &$build, BlockPluginInterface $block) {
$build['#pre_render'][] = 'private_message_nodejs_block_view_private_message_notification_block_pre_render';
}
/**
* Custom prerender callback for the private message notification block.
*
* Disables polling in the private notification block, as it is handled instead
* by nodejs.
*/
function private_message_nodejs_block_view_private_message_notification_block_pre_render($build) {
$build['content']['#attached']['drupalSettings']['privateMessageNotificationBlock']['ajaxRefreshRate'] = 0;
return $build;
}
<?php
namespace Drupal\private_message_nodejs\Ajax;
use Drupal\Core\Ajax\CommandInterface;
/**
* Ajax command to return autocomplete member results to the browser.
*/
class PrivateMessageNodejsTriggerUnreadThreadCountUpdateCommand implements CommandInterface {
/**
* The user IDs of the members whose unread thread count should be updated.
*
* @var array
*/
protected $uids;
/**
* Constructs a PrivateMessageNodejsTriggerInboxUpdateCommand object.
*
* @param array $uids
* The user IDs of the members whose unread thread count should be updated.
*/
public function __construct(array $uids) {
$this->uids = $uids;
}
/**
* {@inheritdoc}
*/
public function render() {
return [
'command' => 'privateMessageNodejsTriggerUnreadThreadCountUpdateCommand',
'uids' => $this->uids,
];
}
}
......@@ -6,6 +6,7 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\private_message\Form\PrivateMessageForm;
use Drupal\private_message_nodejs\Ajax\PrivateMessageNodejsTriggerInboxUpdateCommand;
use Drupal\private_message_nodejs\Ajax\PrivateMessageNodejsTriggerNewMessagesCommand;
use Drupal\private_message_nodejs\Ajax\PrivateMessageNodejsTriggerUnreadThreadCountUpdateCommand;
/**
* Defines the private message form.
......@@ -27,6 +28,7 @@ class PrivateMessageNodejsForm extends PrivateMessageForm {
if (!empty($uids)) {
$response->addCommand(new PrivateMessageNodejsTriggerInboxUpdateCommand($uids));
$response->addCommand(new PrivateMessageNodejsTriggerUnreadThreadCountUpdateCommand($uids));
}
return $response;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment