0

Hello I have a basic chat room set up on action cable and was wondering whether there was a way to give the current user a temporary username while posting in the chat room? preferably set up so they have to type their username In before they are allowed to chat?

Here the code I have:

this is the view:

<h1>Chat room</h1>

<div id="messages">
 <%= render @messages %>
</div>

<form>
 <label>Say something:</label><br>
 <input type="text" data-behavior="room_speaker">

</form>

this is the room channel:

class RoomChannel < ApplicationCable::Channel
 def subscribed
 stream_from "room_channel"
end

def unsubscribed
# Any cleanup needed when channel is unsubscribed
end

def speak(data)
  Message.create! content: data['message']
end
end

the message broadcast job:

class MessageBroadcastJob < ApplicationJob
queue_as :default

def perform(message)
ActionCable.server.broadcast 'room_channel', message:       render_message(message)
end

private

def render_message(message)
ApplicationController.renderer.render(partial: 'messages/message',   locals: { message: message })
end
end

and the coffee script:

  App.room = App.cable.subscriptions.create "RoomChannel",
    connected: ->
      # Called when the subscription is ready for use on the server

    disconnected: ->
      # Called when the subscription has been terminated by the server


    received: (data) ->
      $('#messages').append data['message']

    speak: (message) ->
      @perform 'speak' , message: message



  $(document).on 'keypress', '[data-behavior~=room_speaker]', (event) ->
    if event.keyCode is 13
      App.room.speak event.target.value
      event.target.value = ''
      event.preventDefault();

here is my controller:

 class RoomsController < ApplicationController
 def index
  @messages = Message.all
 end

end

the page that I render:

<div class="message">
  <p><%=message.content%></p>
</div>
Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
dave
  • 15
  • 1
  • 4

1 Answers1

2

Solution 1

Initially redirect user to page where there will be textbox to enter username Once user enters username and click on submit, redirect him/her to chat page. Now you have params[:user_name] just create @username in chat action and make it a hidden variable in your chat form. (i.e in form where user enters chat message).

Now your form will look like this

class RoomsController < ApplicationController

 #index action will render form with just text_field to enter username and submit

 def index
 end

 # Now chat_window will handle you chat_form
 # From index action you will receive params username. Just create object with it
 # so that you can refer it in chat form
 def chat_window 
  @username = params[:user_name] 
  @messages = Message.all
 end
end

NOTE: Create route accordingly

Now change your existing form like below.This form will have hidden @username value.

<form>
 <label>Say something:</label><br>
 <input type="hidden" id="user_name" value="<%=@username%>">
 <input type="text" data-behavior="room_speaker">
</form>

Solution 2:

You can just do it in single form using hide and show functionality. Here I am initially hiding chat form and making only username div visible. Once he/she enters username, Will show chat_form and username will be appended to username hidden field in that form. That's it.

<h1>Chat room</h1>

<div class="user-block">
<input type="text" id="temp_user" placeholder="Enter Username"></input>
<button id="submit_username">Ok</button>
</div>


<div class="chat-block" style="display: none;">
<div id="messages">

</div>

<form>
 <label>Say something:</label><br>
 <input type="hidden" id="user_name" value="anonyms"></input>
 <input type="text" data-behavior="room_speaker">

</form>
</div>



<script>

$(document).ready(function(){
 $("#submit_username").click(function(){
    $(".chat-block").show();
    $(".user-block").hide()
    $("#user_name").val($("#temp_user").val());
 });
});
</script>

Final steps

Once on of above things done.Just send username as well along with your message to Room Channel classe's speak

  App.room = App.cable.subscriptions.create "RoomChannel",
    connected: ->
      # Called when the subscription is ready for use on the server

    disconnected: ->
      # Called when the subscription has been terminated by the server


    received: (data) ->
      $('#messages').append data['message']

    speak: (message, user_name) ->
      @perform 'speak' , message: message, user_name: user_name



  $(document).on 'keypress', '[data-behavior~=room_speaker]', (event) ->
    if event.keyCode is 13
      App.room.speak event.target.value, $("#user_name").val()
      event.target.value = ''
      event.preventDefault();

And in your Room Channel will have username like this

def speak(data, user_name)
  # here you got user_name.Do whatever.
  # Either create field in message model called user_name or Separate User model.
  Message.create! content: data['message']
end
halfer
  • 19,824
  • 17
  • 99
  • 186
krishnar
  • 2,537
  • 9
  • 23