commit
bb5e5eff15
|
@ -17,6 +17,7 @@ let localstream;
|
|||
|
||||
window.onload = () => {
|
||||
currentUser = document.getElementById("current-user").innerHTML;
|
||||
console.log(currentUser)
|
||||
localVideo = document.getElementById("local-video");
|
||||
remoteVideoContainer = document.getElementById("remote-video-container");
|
||||
};
|
||||
|
@ -40,17 +41,49 @@ document.onreadystatechange = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
// find chatroom
|
||||
// const handleJoinSession = async () => {
|
||||
// App.session = await App.cable.subscriptions.create("VideoSessionChannel", {
|
||||
// connected: () => {
|
||||
// broadcastData({
|
||||
// type: JOIN_ROOM,
|
||||
// from: currentUser
|
||||
// });
|
||||
// },
|
||||
// received: data => {
|
||||
// console.log("received", data);
|
||||
// if (data.from === currentUser) return;
|
||||
// switch (data.type) {
|
||||
// case JOIN_ROOM:
|
||||
// return joinRoom(data);
|
||||
// case EXCHANGE:
|
||||
// if (data.to !== currentUser) return;
|
||||
// return exchange(data);
|
||||
// case REMOVE_USER:
|
||||
// return removeUser(data);
|
||||
// default:
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
const chatroomId = document.getElementById('chatroom-hook').dataset["chatroomId"]
|
||||
|
||||
const handleJoinSession = async () => {
|
||||
App.session = await App.cable.subscriptions.create("VideoSessionChannel", {
|
||||
App['chatroom' + chatroomId] = await App.cable.subscriptions.create({
|
||||
channel: "ChatRoomsChannel",
|
||||
room: chatroomId
|
||||
}, {
|
||||
connected: () => {
|
||||
console.log(chatroomId)
|
||||
broadcastData({
|
||||
type: JOIN_ROOM,
|
||||
from: currentUser
|
||||
from: currentUser,
|
||||
room: chatroomId
|
||||
});
|
||||
},
|
||||
received: data => {
|
||||
console.log("received", data);
|
||||
console.log(data)
|
||||
if (data.from === currentUser) return;
|
||||
switch (data.type) {
|
||||
case JOIN_ROOM:
|
||||
|
@ -88,7 +121,6 @@ const joinRoom = data => {
|
|||
};
|
||||
|
||||
const removeUser = data => {
|
||||
console.log("removing user", data.from);
|
||||
let video = document.getElementById(`remoteVideoContainer+${data.from}`);
|
||||
video && video.remove();
|
||||
delete pcPeers[data.from];
|
||||
|
@ -96,18 +128,21 @@ const removeUser = data => {
|
|||
|
||||
|
||||
const broadcastData = data => {
|
||||
fetch("sessions", {
|
||||
if (data.type === EXCHANGE) {
|
||||
console.log("yayyy")
|
||||
}
|
||||
fetch("chat_room_sessions", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
headers: { "content-type": "application/json" }
|
||||
headers: { "content-type": "application/json", "X-CSRF-Token": document.querySelector('meta[name=csrf-token]').content }
|
||||
});
|
||||
};
|
||||
|
||||
const createPC = (userId, isOffer) => {
|
||||
let pc = new RTCPeerConnection(ice);
|
||||
let test = userId
|
||||
pcPeers[userId] = pc;
|
||||
pc.addStream(localstream);
|
||||
|
||||
if (isOffer) {
|
||||
pc
|
||||
.createOffer()
|
||||
|
@ -117,7 +152,8 @@ const createPC = (userId, isOffer) => {
|
|||
type: EXCHANGE,
|
||||
from: currentUser,
|
||||
to: userId,
|
||||
sdp: JSON.stringify(pc.localDescription)
|
||||
sdp: JSON.stringify(pc.localDescription),
|
||||
room: chatroomId
|
||||
});
|
||||
})
|
||||
.catch(logError);
|
||||
|
@ -129,7 +165,8 @@ const createPC = (userId, isOffer) => {
|
|||
type: EXCHANGE,
|
||||
from: currentUser,
|
||||
to: userId,
|
||||
candidate: JSON.stringify(event.candidate)
|
||||
candidate: JSON.stringify(event.candidate),
|
||||
room: chatroomId
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -186,7 +223,8 @@ const exchange = data => {
|
|||
type: EXCHANGE,
|
||||
from: currentUser,
|
||||
to: data.from,
|
||||
sdp: JSON.stringify(pc.localDescription)
|
||||
sdp: JSON.stringify(pc.localDescription),
|
||||
room: chatroomId
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -50,6 +50,10 @@ a:hover {
|
|||
color: $icon;
|
||||
font-size: 25px;
|
||||
}
|
||||
button {
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class ChatRoomsChannel < ApplicationCable::Channel
|
||||
def subscribed
|
||||
stream_from "chat_room_#{params[:room]}"
|
||||
end
|
||||
|
||||
def unsubscribed
|
||||
# Any cleanup needed when channel is unsubscribed
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
class NotificationsChannel < ApplicationCable::Channel
|
||||
def subscribed
|
||||
stream_from "notifications"
|
||||
end
|
||||
|
||||
def unsubscribed
|
||||
# Any cleanup needed when channel is unsubscribed
|
||||
end
|
||||
end
|
|
@ -1,6 +1,24 @@
|
|||
class ChatRoomsController < ApplicationController
|
||||
|
||||
def create
|
||||
def show
|
||||
@chat_room = ChatRoom.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
# HTTP status code 200 with an empty body
|
||||
head :no_content
|
||||
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>11123213213213123213"
|
||||
puts params
|
||||
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>11123213213213123213"
|
||||
|
||||
ActionCable.server.broadcast "chat_room_#{params[:room]}", session_params
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def session_params
|
||||
# SDP = Session description protocol (codec info from client)
|
||||
# Candidate = ICE candidates (e.g. TURN and STUN server)
|
||||
params.permit(:type, :from, :to, :sdp, :candidate, :room)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class PagesController < ApplicationController
|
||||
# skip_before_action :authenticate_user!, only: [:call]
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
def call
|
||||
end
|
||||
|
@ -9,4 +10,63 @@ class PagesController < ApplicationController
|
|||
|
||||
def home
|
||||
end
|
||||
|
||||
def cable_testing
|
||||
chatroom = 'chat_room_' + params[:chat_room_id]
|
||||
puts params
|
||||
ActionCable.server.broadcast(chatroom, { message: 'test' })
|
||||
head :ok
|
||||
end
|
||||
|
||||
def establish_call
|
||||
head :ok
|
||||
puts "params: #{params}"
|
||||
chat_room = ChatRoom.create!
|
||||
puts "Created chat room with id: #{chat_room.id}"
|
||||
chat_room_participation = ChatRoomParticipation.create!(chat_room: chat_room, user: current_user)
|
||||
puts "Created chat room participation with user: #{current_user.email} assigned to chat_room #{chat_room.id}"
|
||||
puts "Subscribed user to chat room"
|
||||
|
||||
contact = User.find(params[:contact_id])
|
||||
request = Request.create!(chat_room: chat_room, user: contact)
|
||||
puts "Made a request to call #{contact.email}"
|
||||
ActionCable.server.broadcast('notifications', {
|
||||
message: {
|
||||
user_id: contact.id,
|
||||
chat_room_id: chat_room.id
|
||||
}
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
def accept_call
|
||||
puts "-----------------------------------------"
|
||||
puts params
|
||||
puts "IT WORKED"
|
||||
chat_room = ChatRoom.find(params[:chat_room_id])
|
||||
request = Request.where("user_id = ? AND chat_room_id = ?", current_user.id, chat_room.id)
|
||||
|
||||
request[0].accepted = true
|
||||
puts "create new chat room participation"
|
||||
chat_room_participation = ChatRoomParticipation.create!(chat_room: chat_room, user: current_user)
|
||||
puts "Created chat room participation with user: #{current_user.email} assigned to chat_room #{chat_room.id}"
|
||||
|
||||
other_caller = chat_room.users.find { |u| u != current_user } # remember to update this later
|
||||
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>..HHHHHHHHH"
|
||||
puts other_caller
|
||||
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>..HHHHHHHHH"
|
||||
# redirect caller to chat room
|
||||
ActionCable.server.broadcast('notifications', {
|
||||
head: 302, # redirection code, just to make it clear what you're doing
|
||||
path: chat_room_path(chat_room), # you'll need to use url_helpers, so include them in your file
|
||||
body: { caller: other_caller.id }
|
||||
}
|
||||
# other_caller, # or however you identify your subscriber
|
||||
)
|
||||
# redirect callee to chat room
|
||||
redirect_to chat_room_path(chat_room)
|
||||
# broadcast another message to caller
|
||||
# head: 302
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
class RequestsController < ApplicationController
|
||||
|
||||
def update
|
||||
request.accepted = true
|
||||
def accept
|
||||
|
||||
# Create new Chat Room
|
||||
end
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
import "bootstrap";
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import ActionCable from 'actioncable'
|
||||
|
||||
// create App object with key cable == new cosumer
|
||||
(function() {
|
||||
window.App || (window.App = {});
|
||||
|
||||
App.cable = ActionCable.createConsumer();
|
||||
|
||||
}).call(this);
|
||||
|
||||
// find chatroom id
|
||||
const chatroomId = document.getElementById('chatroom-hook').dataset["chatroomId"]
|
||||
|
||||
// create subsciptions
|
||||
App['chatroom' + chatroomId] = App.cable.subscriptions.create({
|
||||
channel: 'ChatRoomsChannel',
|
||||
room: chatroomId
|
||||
}, {
|
||||
connected: () => {
|
||||
},
|
||||
received: data => {
|
||||
}
|
||||
})
|
||||
|
||||
// Testing ActionCable
|
||||
const testBtn = document.getElementById('test-btn')
|
||||
testBtn.addEventListener('click', event => {
|
||||
fetch(`/chat_rooms/${chatroomId}/cable_testing` , {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
import ActionCable from 'actioncable'
|
||||
|
||||
// create App object with key cable == new cosumer
|
||||
(function() {
|
||||
window.App || (window.App = {});
|
||||
|
||||
App.cable = ActionCable.createConsumer();
|
||||
|
||||
}).call(this);
|
||||
|
||||
|
||||
const userId = parseInt(document.getElementById("my-user-id").dataset["userId"])
|
||||
let chatRoomId = null
|
||||
|
||||
|
||||
App.cable.subscriptions.create({
|
||||
channel: 'NotificationsChannel'
|
||||
}, {
|
||||
connected: () => {
|
||||
console.log('Connected to NotificationsChannel')
|
||||
},
|
||||
received: data => {
|
||||
// console.log(data["message"]["user_id"])
|
||||
// console.log(userId)
|
||||
console.log("received broadcast")
|
||||
// console.log(data.body)
|
||||
if (data.head === 302 && data.body["caller"] === userId && data.path ) {
|
||||
window.location.pathname = data.path
|
||||
} else if (data["message"]["user_id"] === userId) {
|
||||
console.log("TRIGGER MODAL")
|
||||
const acceptButton = document.getElementById('accept-button')
|
||||
acceptButton.style.display = "block"
|
||||
// const receiveCall = document.getElementById('receive-call')
|
||||
// receiveCall.dataset.toggle = 'modal'
|
||||
// receiveCall.dataset.target ='#calleeModal'
|
||||
// console.log(receiveCall)
|
||||
|
||||
// const calleeModal = document.getElementById('calleeModal')
|
||||
// calleeModal.modal("show")
|
||||
chatRoomId = data["message"]["chat_room_id"]
|
||||
console.log(`user with id: ${userId} needs to subscribe to chatroom ${[chatRoomId]}`)
|
||||
} else {
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const acceptButton = document.getElementById('accept-button')
|
||||
|
||||
acceptButton.addEventListener('click', event => {
|
||||
// event.preventDefault()
|
||||
document.getElementById('chat-room-id').value = chatRoomId
|
||||
})
|
|
@ -1,5 +1,5 @@
|
|||
class ChatRoom < ApplicationRecord
|
||||
has_many :users, through: :chat_room_participations
|
||||
has_many :chat_room_participations
|
||||
has_many :users, through: :chat_room_participations
|
||||
has_many :requests
|
||||
end
|
||||
|
|
|
@ -5,8 +5,8 @@ class User < ApplicationRecord
|
|||
:recoverable, :rememberable, :validatable
|
||||
|
||||
has_many :connections
|
||||
has_many :chat_rooms, through: :chat_room_participations
|
||||
has_many :chat_room_participations
|
||||
has_many :chat_rooms, through: :chat_room_participations
|
||||
has_many :requests
|
||||
|
||||
def contacts
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<button onclick="handleJoinSession()" data-room="<%= @chat_room.id %>">Join Room</button>
|
||||
|
||||
<h1 style="color: white;">This is chatroom #<%= @chat_room.id %></h1>
|
||||
<div id="chatroom-hook" data-chatroom-id='<%= @chat_room.id %>'></div>
|
||||
|
||||
<button id="test-btn">Test Connection</button>
|
||||
<div class="call-container">
|
||||
<div id="remote-video-container">
|
||||
<div id="video_overlays">
|
||||
<video id="local-video" autoplay></video>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="text-color" style="display:none">Random User ID:</span>
|
||||
<span id="current-user" class="text-color" style="display:none"><%= current_user.id %></span>
|
||||
</div>
|
||||
|
||||
|
||||
<%= javascript_pack_tag 'chatrooms' %>
|
|
@ -1,18 +1,30 @@
|
|||
<%
|
||||
def hello_world
|
||||
puts "Hello World"
|
||||
end
|
||||
%>
|
||||
|
||||
<div class="card">
|
||||
<div class="info">
|
||||
<img src="https://kitt.lewagon.com/placeholder/users/ssaunier" alt="" class="profile img-circle" width=65>
|
||||
<div class="text text-color">
|
||||
<p>FirstName LastName</p>
|
||||
<% if contact.nil? || contact.nil? %> <!-- REPLACE WITH FIRST NAME AND LAST NAME -->
|
||||
<p><%= contact.email %></p>
|
||||
<% else %>
|
||||
<p><%= contact.email %></p>
|
||||
<!-- <p><%#= contact.first_name %> <%#= contact.last_name %></p> -->
|
||||
<% end %>
|
||||
<p class="darker">Last call: <%= Time.now %></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="call">
|
||||
<%= link_to "#", 'data-toggle':"modal", 'data-target':"#myModal" do %>
|
||||
<div class="call" data-user-id="<%= contact.id %>">
|
||||
<%= link_to establish_call_path(contact.id), 'data-toggle':"modal", 'data-target':"#myModal" do %>
|
||||
<i class="fas fa-phone"></i>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="vertical-alignment-helper">
|
||||
|
@ -27,7 +39,17 @@
|
|||
<img src="https://kitt.lewagon.com/placeholder/users/ssaunier" alt="" class="profile img-circle" width=150>
|
||||
<div class="modal-text">
|
||||
<h4 class="modal-title" id="myModalLabel">Calling</h4>
|
||||
<h4><strong>FirstName LastName</strong></h4>
|
||||
<h4>
|
||||
<strong>
|
||||
<!-- REPLACE WITH FIRST NAME AND LAST NAME -->
|
||||
<% if contact.nil? || contact.nil? %>
|
||||
<p><%= contact.email %></p>
|
||||
<% else %>
|
||||
<p><%= contact.email %></p>
|
||||
<!-- <p><%#= contact.first_name %> <%#= contact.last_name %></p> -->
|
||||
<% end %>
|
||||
</strong>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
|
||||
<!--
|
||||
<div class="call-container">
|
||||
<div id="remote-video-container">
|
||||
<div id="video_overlays">
|
||||
|
@ -7,7 +7,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
-->
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div class="contacts-container text-color">
|
||||
<div class="contacts half">
|
||||
<h2>Contacts</h2>
|
||||
<% 5.times do %>
|
||||
<%= render "pages/contact" %>
|
||||
<% current_user.contacts.each do |contact| %>
|
||||
<%= render "pages/contact", contact: contact %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="video-feed half">
|
||||
|
@ -14,6 +14,13 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="my-user-id" data-user-id="<%= current_user.id %>"></div>
|
||||
|
||||
<form action="/accept_call" method="post">
|
||||
<input type="hidden" id="chat-room-id" name="chat_room_id" value=""/>
|
||||
<input type="submit" id="accept-button" class="btn btn-primary" id="accept-button" style="display: none;" value="ACCEPT CALL"/>
|
||||
</form>
|
||||
|
||||
<%= javascript_pack_tag 'notifications' %>
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Rails.application.routes.draw do
|
||||
get 'video_sessions/create'
|
||||
|
||||
devise_for :users, path: '', path_names: { sign_out: 'logout'}
|
||||
devise_scope :user do
|
||||
get '/logout', to: 'devise/sessions#destroy'
|
||||
|
@ -15,9 +15,22 @@ Rails.application.routes.draw do
|
|||
|
||||
get '/call', to: 'pages#call'
|
||||
|
||||
get '/establish_call/:contact_id', to: 'pages#establish_call', as: 'establish_call'
|
||||
|
||||
post '/accept_call', to: 'pages#accept_call', as: 'accept_call/'
|
||||
|
||||
patch '/accept_call/:request_id', to: 'requests#update', as: 'update_request'
|
||||
|
||||
get '/contacts', to: 'pages#index'
|
||||
post '/sessions', to: 'video_sessions#create'
|
||||
|
||||
post '/chat_rooms/chat_room_sessions', to: 'chat_rooms#create'
|
||||
|
||||
resources :chat_rooms, only: [ :show ] do
|
||||
# testing action cable
|
||||
post '/cable_testing', to: 'pages#cable_testing'
|
||||
end
|
||||
|
||||
mount ActionCable.server, at: '/cable'
|
||||
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
||||
get '/home', to: 'pages#home'
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@rails/webpacker": "3.5",
|
||||
"actioncable": "^5.2.1",
|
||||
"bootstrap": "3",
|
||||
"jquery": "^3.3.1"
|
||||
},
|
||||
|
|
|
@ -57,6 +57,10 @@ acorn@^5.0.0:
|
|||
version "5.7.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.2.tgz#91fa871883485d06708800318404e72bfb26dcc5"
|
||||
|
||||
actioncable@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/actioncable/-/actioncable-5.2.1.tgz#615428a8a302cec55117d9049f0fd7952011c962"
|
||||
|
||||
ajv-keywords@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
|
||||
|
|
Loading…
Reference in New Issue