Crashtor
Crashtor

Reputation: 1279

Multiple received callbacks in same App.cable.subscription

I'm developing a chat function where I'd like to have several separate events within the same broadcasting channel for:

Along with the regular flow of messages. I have gotten to the point where every single one of these events are correctly hitting the received: (data) -> callback, and displaying correctly to the correct user.

All events are submitted using different triggers on clientside, such as keydown, submit etc and processed differently, but they all in the end hit the same received callback. How can I scope out these events within this same received(data) -> callback to cover functionality as for when a user has stopped typing (but not sent the message?

For instance, when user is typing:

$(".new_im_message").on("focusin",function(e) {
  var values = $("#typing_user").val();
  App.instantmessage.is_typing(values);
});

Processed appropriately and then hits received callback:

  received: (data) ->
    $(".user_is_typing").show();

User is no longer typing, and no message is sent

$(".new_im_message").on("blur",function(e) {
  var values = $("#typing_user").val();
  App.instantmessage.is_blur(values);
});

Processed appropriately and then hits received:

  received: (data) ->
    $(".user_is_typing").show(); 
    $(".user_is_typing").hide(); <<<< can't hide and show at the same time..

How can I split the events up?

  1. Is it possible to have multiple received callbacks within the same channel? received1(data) received2(data) etc.
  2. If not, Can I condition it out depending on which data-type (is_typing) (is_blur) is hitting the received callback?
  3. If not, Do I actually need to split it up into different channels entirely?

Thanks!

Upvotes: 2

Views: 884

Answers (1)

Jay-Ar Polidario
Jay-Ar Polidario

Reputation: 6603

Whenever you call perform() (i.e. when a user types) in your JS code, I suggest passing in the action; i.e. it might look like something like

@perform('typing')

then in your channel (ruby code), you need to have a method that will respond to the action above:

def subscribed
  stream_from 'someidentifier'
  # this line is optional. I just added this to immediately notify everyone in the chatroom that a new user joined in to the chatroom
  ActionCable.server.broadcast 'someidentifier', action: 'subscribed', user_id: current_user.id
end

# this will be called by the JS `@perform('typing')` above
def typing
  # we then broadcast to everyone in that chat room (a.k.a "someidentifier" chatroom), that a specific user is currently typing a message. Modify this as you wish
  ActionCable.server.broadcast 'someidentifier', action: 'typing', user_id: current_user.id
end

def blur
  ActionCable.server.broadcast 'someidentifer', action: 'blur', user_id: current_user.id
end

Then back in your received(data) function in your JS code, we will segregate the action into the appropriate response logic:

received: (data) ->
  switch data.action
    when 'subscribed'
      # do something when a new user (data.user_id) has joined in the chatroom
      console.log(data.user_id)
    when 'typing'
      # do something when a user (data.user_id) is typing 
      console.log(data.user_id)
    when 'blur' 
      # do something when a user (data.user_id) stopped typing
      console.log(data.user_id)

Upvotes: 4

Related Questions