Rearchitect chat channel subscriptions (#409)

* Update chat and add precompilation paths

* Update chat and add precompilation paths

* Adjust assets.rb

* Remove inconsistent test

* Fix check for pathname in chat

* Rearchitect chat channel subscriptions
This commit is contained in:
Ben Halpern 2018-06-08 18:38:53 -04:00 committed by GitHub
parent 923e1acbda
commit 645de032df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 23 deletions

View file

@ -42,7 +42,8 @@ class ChatChannelsController < ApplicationController
if banned_user
banned_user.add_role :banned
banned_user.messages.each(&:destroy!)
Pusher.trigger(@chat_channel.id, "user-banned", { userId: banned_user.id }.to_json)
notification_channels = @chat_channel.chat_channel_memberships.pluck(:user_id).map { |id| "message-notifications-#{id}"}
Pusher.trigger(notification_channels, "user-banned", { userId: banned_user.id }.to_json)
render json: { status: "success", message: "banned!" }, status: 200
else
render json: { status: "error", message: "username not found" }, status: 400

View file

@ -10,7 +10,7 @@ class MessagesController < ApplicationController
begin
message_json = create_pusher_payload(@message)
notification_channels = @message.chat_channel.chat_channel_memberships.pluck(:user_id).map { |id| "message-notifications-#{id}"}
Pusher.trigger([@message.chat_channel.id] + notification_channels, "message-created", message_json)
Pusher.trigger(notification_channels, "message-created", message_json)
success = true
rescue Pusher::Error => e
logger.info "PUSHER ERROR: #{e.message}"
@ -46,6 +46,7 @@ class MessagesController < ApplicationController
message: new_message.message_html,
timestamp: new_message.created_at,
color: new_message.preferred_user_color,
reception_method: "pushed"
}.to_json
end

View file

@ -0,0 +1,13 @@
class PusherController < ApplicationController
def auth
if current_user
response = pusher_client.authenticate(params[:channel_name], params[:socket_id], {
user_id: current_user.id, # => required
})
render json: response
else
render text: 'Forbidden', status: '403'
end
end
end

View file

@ -34,22 +34,12 @@ export default class Chat extends Component {
}
componentDidMount() {
this.state.chatChannels.forEach(channel => {
this.state.chatChannels.slice(0, 3).forEach(channel => {
this.setupChannel(channel.id);
});
setupObserver(this.observerCallback);
}
componentDidUpdate() {
if (!this.state.scrolled) {
scrollToBottom();
}
}
setupChannel = channelId => {
getAllMessages(channelId, this.receiveAllMessages);
setupPusher(this.props.pusherKey, {
channelId,
channelId: `message-notifications-${window.currentUser.id}`,
messageCreated: this.receiveNewMessage,
channelCleared: this.clearChannel,
redactUserMessages: this.redactUserMessages,
@ -59,6 +49,18 @@ export default class Chat extends Component {
this.handleChannelOpenSuccess,
null,
);
}
componentDidUpdate() {
if (!this.state.scrolled) {
scrollToBottom();
}
}
setupChannel = channelId => {
if (this.state.messages[channelId].length === 0 || this.state.messages[channelId][0].reception_method === 'pushed'){
getAllMessages(channelId, this.receiveAllMessages);
}
};
observerCallback = entries => {
@ -161,6 +163,7 @@ export default class Chat extends Component {
handleSwitchChannel = e => {
e.preventDefault();
this.setupChannel(e.target.dataset.channelId);
this.setState({
activeChannelId: parseInt(e.target.dataset.channelId),
scrolled: false,

View file

@ -2,10 +2,15 @@ import Pusher from 'pusher-js';
export default function setupPusher(key, callbackObjects) {
const pusher = new Pusher(key, {
authEndpoint: '/pusher/auth',
auth: {
headers: {
'X-CSRF-Token': window.csrfToken
}
},
cluster: 'us2',
encrypted: true,
});
const channel = pusher.subscribe(callbackObjects.channelId.toString());
channel.bind('message-created', callbackObjects.messageCreated);
channel.bind('channel-cleared', callbackObjects.channelCleared);

View file

@ -10,7 +10,8 @@ class ChatChannel < ApplicationRecord
def clear_channel
messages.each(&:destroy!)
Pusher.trigger(id, "channel-cleared", { chat_channel_id: id }.to_json)
notification_channels = chat_channel_memberships.pluck(:user_id).map { |id| "message-notifications-#{id}"}
Pusher.trigger(notification_channels, "channel-cleared", { chat_channel_id: id }.to_json)
true
rescue Pusher::Error => e
logger.info "PUSHER ERROR: #{e.message}"

View file

@ -102,6 +102,8 @@ Rails.application.routes.draw do
get "/💌" => "chat_channels#index"
get "/💌/:slug" => "chat_channels#index"
post "/pusher/auth" => "chat_channels#index"
# resources :users
get "/social_previews/article/:id" => "social_previews#article"

View file

@ -1,9 +1,14 @@
const { environment } = require('@rails/webpacker');
const customConfig = require('./custom');
// const { environment } = require('@rails/webpacker');
// const customConfig = require('./custom');
environment.config.set('resolve.extensions', ['.foo', '.bar']);
environment.config.set('output.filename', '[name].js');
environment.config.merge(customConfig);
environment.config.delete('output.chunkFilename');
// environment.config.set('resolve.extensions', ['.foo', '.bar']);
// environment.config.set('output.filename', '[name].js');
// environment.config.merge(customConfig);
// environment.config.delete('output.chunkFilename');
module.exports = environment;
// module.exports = environment;
const { environment } = require('@rails/webpacker')
module.exports = environment