Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIKE] Replace Poxa with Action Cable #3105

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app/assets/javascripts/application.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#= require_tree ./frontend
#= require ./frontend/financial_summary_tables/fst_base.js
#= require_tree ./frontend/financial_summary_tables
#= require channels
#
#= require offline

Expand Down Expand Up @@ -739,7 +740,7 @@ jQuery ->

CollaboratorsLog.log("[COLLABORATOR MODE] ------------ redirect_url ----------- " + redirect_url)

if ApplicationCollaboratorsAccessManager.does_im_current_editor()
if ApplicationCollaboratorsAccessManager.i_am_current_editor()
CollaboratorsLog.log("[COLLABORATOR MODE] -------------I'm EDITOR---------- SAVE AND REDIRECT")
# If I'm current editor
# -> then save form data and once it saved redirect me to proper section in a callback
Expand All @@ -754,7 +755,7 @@ jQuery ->
window.location.href = redirect_url

else
CollaboratorsLog.log("[STANDART MODE] ----------------------- ")
CollaboratorsLog.log("[STANDARD MODE] ----------------------- ")

autosave()

Expand Down
6 changes: 6 additions & 0 deletions app/assets/javascripts/channels/index.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#= require action_cable
#= require_self
#= require_tree .

@App = {}
App.cable = ActionCable.createConsumer()
Original file line number Diff line number Diff line change
@@ -1,133 +1,63 @@
window.ApplicationCollaboratorsAccessManager =

register_member: (member) ->
member_info = ApplicationCollaboratorsAccessManager.get_member_info(member)

if member.id is String(window.pusher_current_channel.members.me.id)
CollaboratorsLog.log("[ME IS MEMBER] ------------------------- " + member_info)
else
CollaboratorsLog.log("[ANOTHER MEMBER] ------------------------- " + member_info)

set_access_mode: () ->
editor = ApplicationCollaboratorsAccessManager.current_editor()
CollaboratorsLog.log("[SET ACCESS MODE] ------------ CURRENT EDITOR IS -------- " + editor.id)
editor_id = ApplicationCollaboratorsAccessManager.current_editor_id()
# CollaboratorsLog.log("[SET ACCESS MODE] ------------ CURRENT EDITOR IS -------- " + editor_id)
previous_editor_id = window.pusher_last_editor_id
console.log("previous editor was: " + previous_editor_id)
ApplicationCollaboratorsAccessManager.track_current_editor(editor_id)

ApplicationCollaboratorsAccessManager.track_current_editor(editor)

if ApplicationCollaboratorsAccessManager.does_im_current_editor()
if ApplicationCollaboratorsAccessManager.i_am_current_editor()
CollaboratorsLog.log("[EDITOR MODE] ----------------------")

else
CollaboratorsLog.log("[READ ONLY MODE] ----------------------")

ApplicationCollaboratorsFormLocker.lock_current_form_section()
ApplicationCollaboratorsEditorBar.render_collaborators_bar()
ApplicationCollaboratorsEditorBar.hide_collaborators_bar()

login_to_the_room: (current_step) ->
# Unsubscribe client from current section room
room = window.pusher_current_channel.name;
window.pusher.unsubscribe(window.pusher_current_channel.name);
if previous_editor_id != undefined && previous_editor_id != ApplicationCollaboratorsAccessManager.current_editor_id()
CollaboratorsLog.log("[NOW IM EDITOR] ---- REFRESHING PAGE")

# Clean up last editor id as we switched to another section
window.pusher_last_editor_id = null;
ApplicationCollaboratorsEditorBar.show_loading_bar()

# And hide collaborators info bar
ApplicationCollaboratorsEditorBar.hide_collaborators_bar()
# Redirect user to same page in order to get the new changes
redirect_url = $(".js-step-link.step-current a").attr('href')
redirect_url += "&form_refresh=true"

CollaboratorsLog.log("[TAB SWITCH] ------------- Log out from (" + room + ") to " + current_step + " --------------------")
#
# In case it was an attempt to submit and validation errors are present
# then we are passing validate_on_form_load option
# in order to show validation errors to user after redirection
#
if window.location.href.search("validate_on_form_load") > 0
redirect_url += "&validate_on_form_load=true"

# Set new pusher section
window.pusher_section = current_step;

# Set new login timestamp for user
timestamp = new Date().getTime();

# Init new room based on selected section
ApplicationCollaboratorsConnectionManager.init_pusher(timestamp)
ApplicationCollaboratorsConnectionManager.init_room()

my_position_in_members_queue: () ->
i = 0
my_index = 0

members = window.pusher_current_channel.members
me = members.me

members.each (member) ->
if member.id is String(me.id)
my_index = i

i += 1
window.location.href = redirect_url
else
CollaboratorsLog.log("[READ ONLY MODE] ----------------------")

my_index
ApplicationCollaboratorsFormLocker.lock_current_form_section()
ApplicationCollaboratorsEditorBar.render_collaborators_bar()

does_im_current_editor: () ->
ApplicationCollaboratorsAccessManager.my_position_in_members_queue() == 0
i_am_current_editor: () ->
ApplicationCollaboratorsAccessManager.current_editor_id() == window.user_id &&
window.tab_ident == ApplicationCollaboratorsAccessManager.current_editor().tab_ident

im_in_viewer_mode: () ->
!ApplicationCollaboratorsAccessManager.does_im_current_editor()

normalized_members_array: () ->
list = []

members = window.pusher_current_channel.members
members.each (member) ->
list.push(member)

return list
!ApplicationCollaboratorsAccessManager.i_am_current_editor()

get_member_info: (m) ->
return ("ID: " + m.id + ", NAME: " + m.info.name + ", JOINED AT: " + m.info.joined_at)
current_editor_id: () ->
editor_id = window.current_channel_members.split("/").find((el) => el.includes("EDITOR")).split(":")[0]

return editor_id

current_editor: () ->
editor = ApplicationCollaboratorsAccessManager.normalized_members_array()[0]
member_info = ApplicationCollaboratorsAccessManager.get_member_info(editor)

CollaboratorsLog.log("[CURRENT EDITOR] ------------- " + member_info + " --------------------")

return editor

try_mark_as_editor: () ->
editor = ApplicationCollaboratorsAccessManager.current_editor()

if ApplicationCollaboratorsAccessManager.can_be_marked_as_editor(editor)
CollaboratorsLog.log("[NOW IM EDITOR] ----------------------")

ApplicationCollaboratorsEditorBar.show_loading_bar()

# Redirect user to same page in order to login him
redirect_url = $(".js-step-link.step-current a").attr('href')
redirect_url += "&form_refresh=true"

#
# In case if was attempt to submit and validation errors are present
# then we are passing validate_on_form_load option
# in order to show validation errors to user after redirection
#
if window.location.href.search("validate_on_form_load") > 0
redirect_url += "&validate_on_form_load=true"

window.location.href = redirect_url
else
#
# If I'm not next in queue to be marked as editor
# or I'm already editor
#
# Then do not need to refresh page
#

if window.pusher_last_editor_id == editor.id
CollaboratorsLog.log("[ACCESS CALC] ---------------------- I'M ALREADY EDITOR OF CURRENT TAB!")
else
CollaboratorsLog.log("[ACCESS CALC] ---------------------- NOPE - I STILL HAVE TO WAIT!")

track_current_editor: (editor) ->
window.pusher_last_editor_id = editor.id

can_be_marked_as_editor: (editor) ->
#
# If I'm next in queue to join room as editor
# and I'm not previous editor
#
ApplicationCollaboratorsAccessManager.does_im_current_editor() &&
window.pusher_last_editor_id != editor.id
editor = window.current_channel_members.split("/").find((el) => el.includes("EDITOR")).split(":")
editor_info = {
id: editor[0],
tab_ident: editor[1],
email: editor[2],
name: editor[3]
}

editor_info

track_current_editor: (editor_id) ->
window.pusher_last_editor_id = editor_id
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
window.ApplicationCollaboratorsConnectionManager =

init: (form_id, p_host, p_port, p_key, rails_env, timestamp) ->
init: (form_id, user_id, rails_env) ->

#
# Checking if browser supports WebSockets technology
Expand All @@ -9,79 +9,35 @@ window.ApplicationCollaboratorsConnectionManager =

window.form_id = form_id

window.pusher_host = p_host
window.pusher_port = p_port

window.pusher_key = p_key
window.rails_env = rails_env
window.user_id = user_id

if rails_env == "staging" || rails_env == "production"
window.pusher_encrypted = true
else
window.pusher_encrypted = false
window.tab_ident = ApplicationCollaboratorsConnectionManager.get_tab_ident()

window.pusher_section = $(".js-step-link.step-current").attr('data-step')
window.form_section = $(".js-step-link.step-current").attr('data-step')

ApplicationCollaboratorsConnectionManager.init_pusher(timestamp)
ApplicationCollaboratorsConnectionManager.init_room()
ApplicationCollaboratorsGeneralRoomTracking.login()

init_pusher: (timestamp) ->
CollaboratorsLog.log("[PUSHER INIT] form_id: " + window.form_id + ", host: " + window.pusher_host + ", port: " + window.pusher_port + ", key: " + window.pusher_key + ", enc: " + window.pusher_encrypted + ", section: " + window.pusher_section)

# Init Pusher to use own Poxa server
pusher_ops = {
wsHost: window.pusher_host,
wsPort: window.pusher_port,
authTransport: 'jsonp',
authEndpoint: "/users/form_answers/" + window.form_id + "/collaborator_access/auth/" + window.pusher_section + "/" + timestamp
}

# Use encryption on live and staging
# as they are using HTTPS
#
if window.pusher_encrypted == "true"
pusher_ops["encrypted"] = true
CollaboratorsLog.log("[PUSHER OPS] encryption turned on!")
else
CollaboratorsLog.log("[PUSHER OPS] encryption turned off!")

window.pusher = new Pusher(window.pusher_key, pusher_ops)

# Check connection status
connection_status = pusher.connection.state
CollaboratorsLog.log("PUSHER STATUS: " + connection_status)


init_room: () ->
# Introduce new channel
channel_name = 'presence-chat-' + window.rails_env + "-" + window.form_id + '-sep-' + window.pusher_section

CollaboratorsLog.log("[PUSHER INIT ROOM] ------------------------ channel_name: " + channel_name)

window.pusher_current_channel = window.pusher.subscribe(channel_name)

# Check if subscription was successful
window.pusher_current_channel.bind 'pusher:subscription_succeeded', (members) ->
CollaboratorsLog.log('[subscription_succeeded] Count ' + members.count)

ApplicationCollaboratorsAccessManager.set_access_mode()
members.each (member) =>
ApplicationCollaboratorsAccessManager.register_member(member)
channel_name = 'presence-chat-' + window.rails_env + "-" + window.form_id + '-sep-' + window.form_section

return
CollaboratorsLog.log("[INIT ROOM] ------------------------ channel_name: " + channel_name)

# Handle member removed
window.pusher_current_channel.bind 'pusher:member_removed', (member) ->
CollaboratorsLog.log('[member_removed] Count ' + window.pusher_current_channel.members.count)
window.App.collaborators = App.cable.subscriptions.create { channel: "CollaboratorsChannel", channel_name: channel_name, user_id: window.user_id, current_tab: window.tab_ident },
connected: ->
console.log("connected")

received: (data) ->
console.log("receieved data", data.collaborators)

ApplicationCollaboratorsAccessManager.try_mark_as_editor()
window.current_channel_members = data.collaborators
ApplicationCollaboratorsAccessManager.set_access_mode()

return
disconnected: ->
console.log("disconnected")

# Handle member added
window.pusher_current_channel.bind 'pusher:member_added', (member) ->
CollaboratorsLog.log('[member_added] Count ' + window.pusher_current_channel.members.count)
ApplicationCollaboratorsAccessManager.register_member(member)
get_tab_ident: () ->
document.cookie.split('; ').find((c) => c.split("=")[0] == 'public_tab_ident').split('=')[1]

return
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ window.ApplicationCollaboratorsEditorBar =

render_collaborators_bar: () ->
editor = ApplicationCollaboratorsAccessManager.current_editor()
currentEditorName = editor.info.name + " (" + editor.info.email + ")"
currentEditorName = editor.name + " (" + editor.email + ")"

members = window.pusher_current_channel.members
me = members.me
me = window.user_id

if me.info.email == editor.info.email
if me == editor.id
header = "You cannot edit this section unless you close it elsewhere first."
message = "It looks like you have already opened this section in another tab or window. To avoid data-saving issues, you can only have it open in one tab or window at a time. Please close the other tabs or windows to continue editing."
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,19 @@ window.ApplicationCollaboratorsGeneralRoomTracking =

CollaboratorsLog.log("[PUSHER INIT GENERAL ROOM] ------------------------ channel_name: " + channel_name)

general_channel = window.pusher.subscribe(channel_name)
window.App.generalRoom = App.cable.subscriptions.create { channel: "GeneralRoomChannel", channel_name: channel_name, user_id: window.user_id },
connected: ->
console.log("connected to GENERAL ROOM")

# Check if subscription was successful
# and track number of max members in room
#
general_channel.bind 'pusher:subscription_succeeded', (members) ->
CollaboratorsLog.log('[GENERAL_ROOM subscription_succeeded] Count: ' + members.count)
window.pusher_max_members_count = members.count
received: (data) ->
console.log("receieved data", data.collaborators)

return
window.general_room_members = data.collaborators
ApplicationCollaboratorsAccessManager.set_access_mode()

# Handle member added
general_channel.bind 'pusher:member_added', (member) ->
members_count = general_channel.members.count
CollaboratorsLog.log('[GENERAL_ROOM member_added] Count: ' + members_count)

if window.pusher_max_members_count < members_count
window.pusher_max_members_count = members_count

return
disconnected: ->
console.log("disconnected")

there_are_other_collaborators_here: () ->
window.pusher_max_members_count &&
window.pusher_max_members_count > 1
window.general_room_members &&
window.general_room_members.split('/').length > 1
2 changes: 1 addition & 1 deletion app/assets/javascripts/frontend/form-validation.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ window.FormValidation =
qRef = question.attr("data-question_ref")
qTitle = $.trim(question.find("h2").first().text())

if typeof console != "undefined"
if typeof console != "undefined" && false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[TODO] remove once testing is complete - this output will muddy the waters

console.log "-----------------------------"
console.log("[STEP]: " + stepTitle)
console.log(" [QUESTION] " + qRef + ": "+ qTitle)
Expand Down
4 changes: 4 additions & 0 deletions app/channels/application_cable/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
4 changes: 4 additions & 0 deletions app/channels/application_cable/connection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
Loading
Loading