Adds the ability to push new posts onto discussions that aren't public. (#17)

It's very frustrating having pusher installed, but not seeing new posts pop up on non public
discussions. This PR simply re-uses the existing channels per user by reading
all similar private user channels (which require authentication) and then pushing
the websocket message over the line. This only happens in case the discussion is
not public and it only sends to connected users.
This commit is contained in:
Daniël Klabbers 2021-03-18 16:58:29 +01:00 committed by GitHub
parent 8eb91ecfc7
commit 4f63399d4a
2 changed files with 47 additions and 13 deletions

View File

@ -9,7 +9,7 @@ import Button from 'flarum/components/Button';
app.initializers.add('flarum-pusher', () => {
const loadPusher = new Promise((resolve) => {
$.getScript('//cdn.jsdelivr.net/npm/pusher-js@3.0.0/dist/pusher.min.js', () => {
$.getScript('//cdn.jsdelivr.net/npm/pusher-js@7.0.3/dist/web/pusher.min.js', () => {
const socket = new Pusher(app.forum.attribute('pusherKey'), {
authEndpoint: app.forum.attribute('apiUrl') + '/pusher/auth',
cluster: app.forum.attribute('pusherCluster'),
@ -21,8 +21,11 @@ app.initializers.add('flarum-pusher', () => {
});
return resolve({
main: socket.subscribe('public'),
user: app.session.user ? socket.subscribe('private-user' + app.session.user.id()) : null
channels: {
main: socket.subscribe('public'),
user: app.session.user ? socket.subscribe('private-user' + app.session.user.id()) : null
},
pusher: socket
});
});
});
@ -31,8 +34,10 @@ app.initializers.add('flarum-pusher', () => {
app.pushedUpdates = [];
extend(DiscussionList.prototype, 'oncreate', function() {
app.pusher.then(channels => {
channels.main.bind('newPost', data => {
app.pusher.then(binding => {
const pusher = binding.pusher;
pusher.bind('newPost', data => {
const params = app.discussions.getParams();
if (!params.q && !params.sort && !params.filter) {
@ -59,8 +64,8 @@ app.initializers.add('flarum-pusher', () => {
});
extend(DiscussionList.prototype, 'onremove', function () {
app.pusher.then(channels => {
channels.main.unbind('newPost');
app.pusher.then(binding => {
binding.pusher.unbind('newPost');
});
});
@ -107,8 +112,10 @@ app.initializers.add('flarum-pusher', () => {
});
extend(DiscussionPage.prototype, 'oncreate', function() {
app.pusher.then(channels => {
channels.main.bind('newPost', data => {
app.pusher.then(binding => {
const pusher = binding.pusher;
pusher.bind('newPost', data => {
const id = String(data.discussionId);
if (this.discussion && this.discussion.id() === id && this.stream) {
@ -129,8 +136,8 @@ app.initializers.add('flarum-pusher', () => {
});
extend(DiscussionPage.prototype, 'onremove', function () {
app.pusher.then(channels => {
channels.main.unbind('newPost')
app.pusher.then(binding => {
binding.pusher.unbind('newPost');
});
});
@ -138,7 +145,9 @@ app.initializers.add('flarum-pusher', () => {
items.remove('refresh');
});
app.pusher.then(channels => {
app.pusher.then(binding => {
const channels = binding.channels;
if (channels.user) {
channels.user.bind('notification', () => {
app.session.user.pushAttributes({

View File

@ -11,6 +11,8 @@ namespace Flarum\Pusher\Listener;
use Flarum\Post\Event\Posted;
use Flarum\User\Guest;
use Flarum\User\User;
use Illuminate\Support\Str;
use Pusher;
class PushNewPost
@ -27,10 +29,33 @@ class PushNewPost
public function handle(Posted $event)
{
$channels = [];
if ($event->post->isVisibleTo(new Guest)) {
$channels[] = 'public';
} else {
// Retrieve private channels, used for each user.
$response = $this->pusher->get_channels([
'filter_by_prefix' => 'private-user'
]);
if (! $response) {
return;
}
foreach ($response->channels as $name => $channel) {
$userId = Str::after($name, 'private-user');
if (($user = User::find($userId)) && $event->post->isVisibleTo($user)) {
$channels[] = $name;
}
}
}
if (count($channels)) {
$tags = $event->post->discussion->tags;
$this->pusher->trigger('public', 'newPost', [
$this->pusher->trigger($channels, 'newPost', [
'postId' => $event->post->id,
'discussionId' => $event->post->discussion->id,
'tagIds' => $tags ? $tags->pluck('id') : null