diff --git a/Gemfile b/Gemfile index ffa11e3..9ff157a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source 'https://rubygems.org' ruby '2.4.4' +gem 'google-cloud-translate' gem 'bootsnap', require: false gem 'devise' gem 'jbuilder', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index ec82a00..9244307 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -42,6 +42,8 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) arel (9.0.0) autoprefixer-rails (9.1.3) execjs @@ -79,11 +81,28 @@ GEM railties (>= 3.2, < 6.0) erubi (1.7.1) execjs (2.7.0) + faraday (0.15.2) + multipart-post (>= 1.2, < 3) ffi (1.9.25) font-awesome-sass (5.0.13) sassc (>= 1.11) globalid (0.4.1) activesupport (>= 4.2.0) + google-cloud-core (1.2.3) + google-cloud-env (~> 1.0) + google-cloud-env (1.0.2) + faraday (~> 0.11) + google-cloud-translate (1.2.1) + faraday (~> 0.13) + google-cloud-core (~> 1.2) + googleauth (~> 0.6.2) + googleauth (0.6.6) + faraday (~> 0.12) + jwt (>= 1.4, < 3.0) + memoist (~> 0.12) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (~> 0.7) http-cookie (1.0.3) domain_name (~> 0.5) i18n (1.1.0) @@ -91,6 +110,7 @@ GEM jbuilder (2.7.0) activesupport (>= 4.2.0) multi_json (>= 1.2) + jwt (2.1.0) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -101,6 +121,7 @@ GEM mini_mime (>= 0.1.1) marcel (0.3.2) mimemagic (~> 0.3.2) + memoist (0.16.0) method_source (0.9.0) mime-types (3.2.2) mime-types-data (~> 3.2015) @@ -111,11 +132,13 @@ GEM minitest (5.11.3) msgpack (1.2.4) multi_json (1.13.1) + multipart-post (2.0.0) netrc (0.11.0) nio4r (2.3.1) nokogiri (1.8.4) mini_portile2 (~> 2.3.0) orm_adapter (0.5.0) + os (1.0.0) pg (0.21.0) pry (0.11.3) coderay (~> 1.1.0) @@ -125,6 +148,7 @@ GEM pry (~> 0.10) pry-rails (0.3.6) pry (>= 0.10.4) + public_suffix (3.0.3) puma (3.12.0) rack (2.0.5) rack-proxy (0.6.4) @@ -181,6 +205,11 @@ GEM sassc (1.12.1) ffi (~> 1.9.6) sass (>= 3.3.0) + signet (0.9.1) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) simple_form (4.0.1) actionpack (>= 5.0) activemodel (>= 5.0) @@ -233,6 +262,7 @@ DEPENDENCIES devise dotenv-rails font-awesome-sass (~> 5.0.9) + google-cloud-translate jbuilder (~> 2.0) listen (~> 3.0.5) pg (~> 0.21) diff --git a/app/controllers/chat_rooms_controller.rb b/app/controllers/chat_rooms_controller.rb index 37b681c..59945ca 100644 --- a/app/controllers/chat_rooms_controller.rb +++ b/app/controllers/chat_rooms_controller.rb @@ -1,7 +1,19 @@ class ChatRoomsController < ApplicationController def show + require "google/cloud/translate" + @chat_room = ChatRoom.find(params[:id]) + + keyfile = ENV['TRANSLATION_CREDENTIALS'] + creds = Google::Cloud::Translate::Credentials.new(keyfile) + + translate = Google::Cloud::Translate.new( + project_id: ENV["PROJECT_ID"], + credentials: creds + ) + + @languages = translate.languages("en") end def create diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 3f14af6..610dbb8 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -12,11 +12,67 @@ class PagesController < ApplicationController def home end + def translate + require 'google/cloud/translate' + + keyfile = ENV["TRANSLATION_CREDENTIALS"] + creds = Google::Cloud::Translate::Credentials.new(keyfile) + + translate = Google::Cloud::Translate.new( + project_id: ENV["PROJECT_ID"], + credentials: creds + ) + original = params[:original] + target = params[:target] + text = params[:text] + translation = translate.translate(text, { from: original, to: target }) + translation.text.gsub!("'", "'") + ActionCable.server.broadcast "chat_room_#{params[:chat_room_id]}", { + translation: translation, + input: params[:input] + } + end + def cable_testing chatroom = 'chat_room_' + params[:chat_room_id] puts params - ActionCable.server.broadcast(chatroom, { message: 'test' }) + user_info = {} + + if current_user.first_name.nil? || current_user.last_name.nil? + user_info[:name] = current_user.email + else + user_info[:name] = "#{current_user.first_name} #{current_user.last_name}" + end + + ActionCable.server.broadcast(chatroom, { + chat_message: { + message: 'test', + user_info: user_info, + time_stamp: Time.now } + }) + head :ok + end + + + def send_message + puts params + chatroom = 'chat_room_' + params[:chat_room_id] + puts params + user_info = {} + + if current_user.first_name.nil? || current_user.last_name.nil? + user_info[:name] = current_user.email + else + user_info[:name] = "#{current_user.first_name} #{current_user.last_name}" + end + + ActionCable.server.broadcast(chatroom, { + chat_message: { + message: params[:message], + user_info: user_info, + time_stamp: Time.now.strftime("%H:%M") } + }) head :ok end diff --git a/app/javascript/packs/chatrooms.js b/app/javascript/packs/chatrooms.js index a29046f..d0ca5a6 100644 --- a/app/javascript/packs/chatrooms.js +++ b/app/javascript/packs/chatrooms.js @@ -19,18 +19,46 @@ App['chatroom' + chatroomId] = App.cable.subscriptions.create({ connected: () => { }, received: data => { - console.log(data) + if (data["chat_message"]) { + const chatMessage = data["chat_message"] + const messagesContainer = document.getElementById('messages-container') + const message = document.createElement("p") + message.innerText = `${chatMessage["time_stamp"]} ${chatMessage["user_info"]["name"]}: ${chatMessage["message"]}` + messagesContainer.appendChild(message) + } else if (data["translation"]) { + if (data["input"] == 1) { + document.getElementById('language-2-input').value = data["translation"].text + } else { + document.getElementById('language-1-input').value = data["translation"].text + } + } else { + console.log(data) + } } }) // Testing ActionCable -const testBtn = document.getElementById('test-btn') -testBtn.addEventListener('click', event => { - fetch(`/chat_rooms/${chatroomId}/cable_testing` , { - method: 'POST', - body: JSON.stringify({}) - }) +// const testBtn = document.getElementById('test-btn') +// testBtn.addEventListener('click', event => { +// fetch(`/chat_rooms/${chatroomId}/cable_testing` , { +// method: 'POST', +// body: JSON.stringify({}) +// }) +// }) + + +const sendBtn = document.getElementById('send-btn') +sendBtn.addEventListener('click', event => { + const chatInput = document.getElementById('chat-input') + if (chatInput && chatInput.value != chatInput.value.match(/^\s*$/g)) { + console.log(chatInput.value) + fetch(`/chat_rooms/${chatroomId}/send_message` , { + method: 'POST', + body: JSON.stringify({message: chatInput.value}), + headers: { "content-type": "application/json", "X-CSRF-Token": document.querySelector('meta[name=csrf-token]').content } + }) + } + chatInput.value = "" }) - diff --git a/app/javascript/packs/translate.js b/app/javascript/packs/translate.js new file mode 100644 index 0000000..0dc49e6 --- /dev/null +++ b/app/javascript/packs/translate.js @@ -0,0 +1,41 @@ +const languageForm1 = document.getElementById('lang-1') +const languageForm2 = document.getElementById('lang-2') +const chatroomId = document.getElementById('chatroom-hook').dataset["chatroomId"] + +languageForm1.addEventListener('submit', event => { + event.preventDefault() + const original = document.getElementById('language-1').value + const target = document.getElementById('language-2').value + const text = document.getElementById('language-1-input').value + + fetch(`/chat_rooms/${chatroomId}/translate` , { + method: 'POST', + body: JSON.stringify({ + original, + target, + text, + input: 1 + }), + headers: { "content-type": "application/json", "X-CSRF-Token": document.querySelector('meta[name=csrf-token]').content } + }) + // post request and change form 1 +}) + +languageForm2.addEventListener('submit', event => { + event.preventDefault() + const original = document.getElementById('language-2').value + const target = document.getElementById('language-1').value + const text = document.getElementById('language-2-input').value + // post request and change form 2 + + fetch(`/chat_rooms/${chatroomId}/translate` , { + method: 'POST', + body: JSON.stringify({ + original: original, + target: target, + text: text, + input: 2 + }), + headers: { "content-type": "application/json", "X-CSRF-Token": document.querySelector('meta[name=csrf-token]').content } + }) +}) diff --git a/app/views/chat_rooms/show.html.erb b/app/views/chat_rooms/show.html.erb index 57f416c..311225c 100644 --- a/app/views/chat_rooms/show.html.erb +++ b/app/views/chat_rooms/show.html.erb @@ -1,4 +1,24 @@ - + + +
+ +
+ +
+ +
+ +
+
+
@@ -9,12 +29,27 @@ + +
+ +
+
+
+
+ +
+ +
+ +
+
+
<%= javascript_pack_tag 'chatrooms' %> <%= javascript_pack_tag 'webrtc' %> - +<%= javascript_pack_tag 'translate' %> diff --git a/config/routes.rb b/config/routes.rb index fd53bde..e36b07b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,6 +30,8 @@ Rails.application.routes.draw do resources :chat_rooms, only: [ :show ] do # testing action cable post '/cable_testing', to: 'pages#cable_testing' + post '/send_message', to: 'pages#send_message' + post '/translate', to: 'pages#translate' end mount ActionCable.server, at: '/cable' diff --git a/translation-credentials.json b/translation-credentials.json new file mode 100644 index 0000000..b065dda --- /dev/null +++ b/translation-credentials.json @@ -0,0 +1,14 @@ +{ + "type": "service_account", + "project_id": "booming-banner-212315", + "private_key_id": "9c2ce218223666d974da8f33e8329e5c6d40a471", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4jSV/s2mp2nri\nJkD4W62aSithmFgd0dNZbPBuDNkhscGXfI4HAYzbWGBHw9gAuN59ezIVFZ3W3IsB\na3scJHup58ZV6zIaeEY5uFhgIlwdohi0iMKvY0eClTBiabu5Drn4OE8IlFX99Ab1\nwhV7WRjGG8YEQ2d1pUHHvS98QeQvb1Km6M9E/4GFib3xcBU0VFO2Evk3AJzK9K1z\nT+DsduloNxAaZfcygWvzhDez2sxftR9PXE1Ek/KQSuATACn11rPUyr/CuHfGSUh6\nypKMUnaYb8EnjrNW/bea/GKjGMzvHubjN/lPEEovXTYANfCXvVMy7ThdQLjS6YIW\nEPvEhS2jAgMBAAECggEAEbiT8jgzHDk7dX3A3VhISjl3Au8S/wIH7l1UlOys6Nxd\nv4MZTDjs4p8Q17NJiYA29QugWn/x4RDaVC+S6bfjHASCefuUmxAThjVaXxjNiZbo\nEmXTc+3vju1ucPTALtvoJZqalDNSMol9JZoWX/rFMzi1gfFK/PP6ZgiXh7H4DEnV\nDtwI8uXs6xGpC5Kr2u2N64RDqk9DbZ6lPLqk1zB1XM1FvApkmsUbSEXZj7CiDemx\nTz23f6VR+eZzgWuaWJQwLwmkWwVgCfUr9KL3Uw92+U/9uvcmNdsC7cwM14RfTx1R\njYkwqjz2RRsiAsuD5ebHxoNDqEIkArf6K+dFJImnOQKBgQD7zFVW22nYg/54JZR1\n3Hyv8ncy6ocPB0+jlESE/m8kPo0RtzGUJxKDTwEZP+y8y2NchI6C1atC/RxE6But\nOUAJLxqD027z4rXo/yNaiDaerZXr/y56pRbhR3wbjuR7vcEFZ3B7bHCrKhgdDYPA\nMTgVxX/2Z3AXwCDpaG2W7LxbpwKBgQC7oYnrF6jzNPCu/FHH4Hhff/2aV0IJO7BQ\nEeY8VADVBHTiYwlnBlG9LkpWFM/YjsGpsfzorztIKDd1N911h2XcL7kgh6+URP75\ntYtQV3iNUbERxdp/rnm97QdZr/W3r9s60q61mX7vMsZK8mPPmwLKvP7YSu0NvFa8\nucidRihtpQKBgAJW/sAE3/HsIBQ7vSpvNxVnemYVudWQ6tOJUC2wM5Yxopv0iNho\nmIpx1H/IkUmb1juI284pcCL6OSYGxiMQ8iBjuKpa76ACjlAw9sIjm+ZTlJ4Ry/vF\nxvWm9WdIJ6ViuQV01Z2//zgH9xtmAcBqdKv3Ht5KTcdauLOSjdomLwXnAoGAfQ7J\nHxFxAVEaznbMh108veJQBKv+Dqti86tKepE+0Lwcr7t0y98xYddVopRSiDN2LwW7\n3NbWu1xawl0O1UP+h0ijqmPlifyGuabgCReT+RUm4QKvhISlDgrK6GNYcirbAxTj\nb5S0PvfnpJJ0Ji5aKQjZDw65e3s5kKZ/aRwW3CUCgYAvWeze0qlg332pZiEtsEnF\nx8CUq7i1phdB3G6cIVdvAee5ce6tvpNiFhECjaUZiykV6zyQY8s8LIyjKTuFXbI9\n2uAvPl7y4PHV5rKJOtuQJOLqaUNgAlklKdUBL2I6vwp/1epxQHUYNeaQv5lC0QT+\nxHrzaiPUQ0ADBUNvUVMIOg==\n-----END PRIVATE KEY-----\n", + "client_email": "starting-account-c76g3v5fh5js@booming-banner-212315.iam.gserviceaccount.com", + "client_id": "105634639063680583591", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/starting-account-c76g3v5fh5js%40booming-banner-212315.iam.gserviceaccount.com" +} + +