Merge branch 'master' into cross

This commit is contained in:
Benjamin Myara 2018-09-03 15:19:04 +01:00 committed by GitHub
commit e6828b3bb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 700 additions and 614 deletions

View File

@ -1,18 +1,26 @@
{ {
"presets": [ "presets": [
["env", { [
"env",
{
"modules": false, "modules": false,
"targets": { "targets": {
"browsers": "> 1%", "browsers": "> 1%",
"uglify": true "uglify": true
}, },
"useBuiltIns": true "useBuiltIns": true
}] }
]
], ],
"plugins": [ "plugins": [
"syntax-dynamic-import", "syntax-dynamic-import",
"transform-object-rest-spread", "transform-object-rest-spread",
["transform-class-properties", { "spec": true }] "transform-runtime",
[
"transform-class-properties",
{
"spec": true
}
]
] ]
} }

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Beatrice Olivera
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1 +1,8 @@
Rails app generated with [lewagon/rails-templates](https://github.com/lewagon/rails-templates), created by the [Le Wagon coding bootcamp](https://www.lewagon.com) team. # polyglot
A video call application made with Ruby on Rails and node.js.
Video calling is made possible with [WebRTC](https://webrtc.org/).
Signaling is done via ActionCable in Rails, a module that handles WebSockets. This section of the project was adapted from `@jeanpaulsio`'s project which can be found [here](https://github.com/jeanpaulsio/action-cable-signaling-server).
This Rails app was generated with [lewagon/rails-templates](https://github.com/lewagon/rails-templates), created by the [Le Wagon coding bootcamp](https://www.lewagon.com) team.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 153 KiB

View File

@ -12,19 +12,23 @@
font-size: 2em; font-size: 2em;
font-weight: bold; font-weight: bold;
a:hover {
color: $primary;
}
} }
.right-align { .right-align {
height: 100%; height: 100%;
width: 16em; width: 16em;
margin-right: 5em; margin-right: 4em;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.links { .links {
display: flex; display: flex;
height: inherit; height: inherit;
div { div {
height: inherit; height: inherit;
display: flex; display: flex;
@ -32,19 +36,26 @@
border-bottom: 5px solid transparent; border-bottom: 5px solid transparent;
&:first-child { &:first-child {
margin-right: 1em; margin-right: 2.5em;
} }
&.active { &.active {
border-bottom: 5px solid $primary; border-bottom: 5px solid $primary;
color: white; color: white;
}
&:hover {
color: white;
}
&.active, &:hover {
a { a {
color: white; color: white;
} }
} }
a { a {
color: #C4C4C4; color: $text-inactive;
text-decoration: none; text-decoration: none;
} }
} }
@ -53,7 +64,28 @@
.profile { .profile {
img { img {
width: 3.25em; width: 3em;
padding: 0.2em;
}
}
.burger-menu {
margin-right: 20px;
color: $primary;
}
.polyglot-dropdown {
background-color: $navbar-background;
li {
a {
color: $text-inactive;
&:hover {
color: white;
background-color: $background;
}
}
} }
} }
} }

View File

@ -14,7 +14,7 @@ $gray-base: $gray;
$brand-primary: $primary; $brand-primary: $primary;
$brand-success: $green; $brand-success: $green;
$brand-info: $yellow; $brand-info: $yellow;
$brand-danger: $red; $brand-danger: $warn;
$brand-warning: $orange; $brand-warning: $orange;
$brand-secondary: $secondary; $brand-secondary: $secondary;
@ -52,3 +52,4 @@ $border-radius-small: 2px;
} }
// Override other variables below! // Override other variables below!
$input-border-focus: $primary;

View File

@ -8,6 +8,7 @@ $orange: #E67E22;
$green: #32B796; $green: #32B796;
$gray: #000000; $gray: #000000;
$light-gray: #F4F4F4; $light-gray: #F4F4F4;
$warn: #3d63cc;
$primary: #F55E4F; $primary: #F55E4F;
$secondary: #5ED17E; $secondary: #5ED17E;
@ -15,4 +16,5 @@ $background: #33333D;
$card-background: #464650; $card-background: #464650;
$navbar-background: #1F1F29; $navbar-background: #1F1F29;
$text-darker: #CDCDCD; $text-darker: #CDCDCD;
$text-inactive: #C4C4C4;
$icon: #EDECEC; $icon: #EDECEC;

View File

@ -1,9 +1,9 @@
// Import Google fonts // Import Google fonts
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,300,700|Raleway:400,100,300,700,500"); @import url("https://fonts.googleapis.com/css?family=Assistant:400,700|Hind:400,700");
// Define fonts for body and headers // Define fonts for body and headers
$body-font: "Open Sans", "Helvetica", "sans-serif"; $body-font: "Hind", "Helvetica", "sans-serif";
$headers-font: "Raleway", "Helvetica", "sans-serif"; $headers-font: "Assistant", "Helvetica", "sans-serif";
// To use a font file (.woff) uncomment following lines // To use a font file (.woff) uncomment following lines
// @font-face { // @font-face {

View File

@ -18,13 +18,13 @@
url('https://unsplash.com/photos/jay5BqVyf5A'); url('https://unsplash.com/photos/jay5BqVyf5A');
.login-content { .login-content {
position: relative; position: relative;
top: -10vh; // top: -10vh;
padding: 50px; padding: 50px;
background-color: white; background-color: white;
width: 25vw; width: 25vw;
min-width: 300px;
border-radius: 3px; border-radius: 3px;
box-shadow: 1px 1px 10px rgba(0,0,0, 0.21); box-shadow: 1px 1px 10px rgba(0,0,0, 0.21);

View File

@ -12,6 +12,7 @@ a:hover {
} }
.card { .card {
min-width: 360px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
background: $card-background; background: $card-background;
@ -73,8 +74,17 @@ a:hover {
} }
.video-content { .video-content {
height: 485px; // height: 485px;
background-color: black;
padding-left: 0.2vw;
display: flex;
justify-content: center;
.flex-video {
height: 100%;
width: 100%;
flex: 1 1 auto;
}
// background-color: black;
} }
.half { .half {
@ -91,6 +101,8 @@ a:hover {
align-items: center; align-items: center;
} }
// Modal
.modal-header { .modal-header {
border-bottom: 0px; border-bottom: 0px;
i { i {
@ -100,6 +112,7 @@ a:hover {
.modal-color { .modal-color {
background-color: $card-background; background-color: $card-background;
min-width: 296px;
} }
.vertical-alignment-helper { .vertical-alignment-helper {
@ -133,17 +146,28 @@ a:hover {
align-items: center; align-items: center;
} }
.modal-flex {
display: flex;
flex-wrap: wrap;
}
@media only screen and (max-width: 1100px) {
.modal-picture {
width: 50px;
}
}
// Contact
.contact { .contact {
color: white; color: white;
} }
.contacts { .contacts {
height: 570px; display: flex;
overflow: scroll; flex-direction: column;
justify-content: center;
} }
.close { .close {
@ -159,12 +183,10 @@ a:hover {
filter: alpha(opacity=20); filter: alpha(opacity=20);
} }
.contacts-list{
height: 90vh;
overflow: scroll;
}

View File

@ -1,4 +1,3 @@
// Specific CSS for your home-page
video { video {
transform: rotateY(180deg); transform: rotateY(180deg);
-webkit-transform:rotateY(180deg); /* Safari and Chrome */ -webkit-transform:rotateY(180deg); /* Safari and Chrome */

View File

@ -1,3 +1,4 @@
// Import page-specific CSS files here. // Import page-specific CSS files here.
@import "home"; @import "home";
@import "contacts" @import "contacts";
@import "settings";

View File

@ -0,0 +1,125 @@
.card-form {
padding: 20px;
}
.card-form-no-hover {
&:hover {
box-shadow: 1px 1px 15px 1px rgba(0, 0, 0, 0.2);
}
}
.input-dropdown {
width: 196px;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {display:none;}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: $primary;
}
input:focus + .slider {
box-shadow: 0 0 1px $primary;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.input-field-text-black {
color: black;
}
.slider.rounded {
border-radius: 3px;
}
.slider.rounded:before {
border-radius: 3px;
}
.settings {
color: white;
}
.no-padding {
padding: 0;
}
.no-margin {
margin: 0;
}
.font-weight-normal {
font-weight: normal;
}
.padding-right {
padding-right: 10px;
}
.margin-right {
margin-right: 10px;
}
.flex-inline {
display: flex;
flex-direction: row;
align-items: center;
}
.space-between {
justify-content: space-between;
}
.center-screen {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
min-height: 80vh;
}

View File

@ -3,7 +3,8 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
height: calc(100vh - 4.5em); // 4.5em is height of navbar padding-top: 30px;
// height: calc(100vh - 4.5em); // 4.5em is height of navbar
form { form {
flex-grow: 1; flex-grow: 1;
@ -22,10 +23,18 @@
img { img {
max-width: 50vw; max-width: 50vw;
padding-top: 30px;
} }
} }
} }
.small-profile-pic {
img {
width: 223px;
margin-bottom: 20px;
}
}
.profile-form { .profile-form {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;

View File

@ -4,6 +4,7 @@
display:flex; display:flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
text-align: center;
h2 { h2 {
font-size: 1.5em; font-size: 1.5em;
@ -21,12 +22,6 @@
margin-right: .5em; margin-right: .5em;
} }
} }
.profile-pic {
display: flex;
align-items: center;
margin-right: 3em;
img {
width: 10em;
} }
} }
@ -34,7 +29,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
color: #f2321f; color: $primary;
h1 { h1 {
margin: 0 0 .5em 0 ; margin: 0 0 .5em 0 ;
} }
@ -46,8 +41,24 @@
color: white; color: white;
} }
} }
.vcenter {
display: inline-block;
vertical-align: middle;
float: none;
} }
.vertical-padding {
padding-top: 5px;
padding-bottom: 5px;
} }
.vertical-margin {
margin-top: 5px;
margin-bottom: 5px;
}
.img-profile {
width: 200px;
height: 200px;
}

View File

@ -6,4 +6,8 @@ class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource) def after_sign_in_path_for(resource)
contacts_path contacts_path
end end
def default_url_options
{ host: ENV["HOST"] || "localhost:3000" }
end
end end

View File

@ -1,6 +1,5 @@
class ConnectionsController < ApplicationController class ConnectionsController < ApplicationController
def new def new
end end
def create def create
@ -10,9 +9,17 @@ class ConnectionsController < ApplicationController
@connection.contact = contact_user @connection.contact = contact_user
if @connection.save if @connection.save
contact_message = nil
if contact_user.first_name.nil? || contact_user.last_name.nil?
contact_message = "#{contact_user.email}"
else
contact_message = "#{contact_user.first_name} #{contact_user.last_name}"
end
flash[:notice] = "Added #{contact_message} to contacts"
redirect_to contacts_path redirect_to contacts_path
else else
flash[:alert] = "Invalid email address!"
render 'new'
end end
end end

View File

@ -13,8 +13,6 @@ class PagesController < ApplicationController
end end
def cable_testing def cable_testing
chatroom = 'chat_room_' + params[:chat_room_id] chatroom = 'chat_room_' + params[:chat_room_id]
puts params puts params

View File

@ -0,0 +1,15 @@
module MetaTagsHelper
def meta_title
content_for?(:meta_title) ? content_for(:meta_title) : DEFAULT_META["meta_title"]
end
def meta_description
content_for?(:meta_description) ? content_for(:meta_description) : DEFAULT_META["meta_description"]
end
def meta_image
meta_image = (content_for?(:meta_image) ? content_for(:meta_image) : DEFAULT_META["meta_image"])
# little twist to make it work equally with an asset or a url
meta_image.starts_with?("http") ? meta_image : image_url(meta_image)
end
end

View File

@ -1,11 +1,15 @@
const triggerModalEvent = () => { const triggerModalEvent = () => {
const btn = document.getElementById("modalTrigger");
const modal = document.getElementById("myModal");
const buttons = document.querySelectorAll(".modalTrigger");
buttons.forEach(btn => {
if (btn) {
btn.addEventListener('click', function(event) { btn.addEventListener('click', function(event) {
$('#myModal').modal('show'); const btnId = btn.getAttribute('data-user-id')
$("#myModal"+`${btnId}`).modal('show');
}); });
} }
})
}
export { triggerModalEvent } export { triggerModalEvent }

View File

@ -4,6 +4,35 @@ import { triggerModalEvent } from "../components/modal.js";
triggerModalEvent(); triggerModalEvent();
// import { profilePageAnimation } from '../users/lesson'; const settingsPage = document.getElementById('settings-page');
const contactsPage = document.getElementById('contacts-page');
const getSiblings = (element) => {
const siblings = [];
let sibling = element.parentNode.firstChild;
const skipMe = element;
for ( ; sibling; sibling = sibling.nextSibling )
if ( sibling.nodeType == 1 && sibling != element )
siblings.push( sibling );
return siblings;
}
const removeActiveClass = (element) => {
const siblings = getSiblings(element);
siblings.forEach(sibling => {
sibling.classList.remove('active');
});
}
if (settingsPage) {
const settings = document.getElementById('settings')
settings.classList.add('active');
removeActiveClass(settings);
}
if (contactsPage) {
const contacts = document.getElementById('contacts')
contacts.classList.add('active');
removeActiveClass(contacts);
}
// profilePageAnimation();

View File

@ -23,13 +23,13 @@ App['chatroom' + chatroomId] = App.cable.subscriptions.create({
}) })
// Testing ActionCable // Testing ActionCable
const testBtn = document.getElementById('test-btn') // const testBtn = document.getElementById('test-btn')
testBtn.addEventListener('click', event => { // testBtn.addEventListener('click', event => {
fetch(`/chat_rooms/${chatroomId}/cable_testing` , { // fetch(`/chat_rooms/${chatroomId}/cable_testing` , {
method: 'POST', // method: 'POST',
body: JSON.stringify({}) // body: JSON.stringify({})
}) // })
}) // })

View File

@ -0,0 +1,14 @@
const contactsVideo = document.getElementById("contacts-video")
try {
const contactsStream = navigator.mediaDevices.getUserMedia({
audio: false,
video: true
}).then(stream => {
contactsVideo.srcObject = stream;
contactsVideo.muted = true;
})
} catch(e) {
console.error(e);
contactsVideo.innerHTML = "Unable to getUserMedia()";
}

View File

@ -1,6 +1,6 @@
import ActionCable from 'actioncable' import ActionCable from 'actioncable'
// create App object with key cable == new cosumer // create App object with key cable == new consumer
(function() { (function() {
window.App || (window.App = {}); window.App || (window.App = {});
@ -12,7 +12,6 @@ import ActionCable from 'actioncable'
const userId = parseInt(document.getElementById("my-user-id").dataset["userId"]) const userId = parseInt(document.getElementById("my-user-id").dataset["userId"])
let chatRoomId = null let chatRoomId = null
App.cable.subscriptions.create({ App.cable.subscriptions.create({
channel: 'NotificationsChannel' channel: 'NotificationsChannel'
}, { }, {
@ -26,17 +25,11 @@ App.cable.subscriptions.create({
// console.log(data.body) // console.log(data.body)
if (data.head === 302 && data.body["caller"] === userId && data.path) { if (data.head === 302 && data.body["caller"] === userId && data.path) {
window.location.pathname = data.path window.location.pathname = data.path
} else if (data["message"]["user_id"] === userId) { } else if (data["message"]["user_id"] === userId) { // Some error appears here but it is not fatal
console.log("TRIGGER MODAL") console.log("TRIGGER MODAL")
const acceptButton = document.getElementById('accept-button') const acceptButton = document.getElementById('accept-button')
acceptButton.style.display = "block" 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"] chatRoomId = data["message"]["chat_room_id"]
console.log(`user with id: ${userId} needs to subscribe to chatroom ${[chatRoomId]}`) console.log(`user with id: ${userId} needs to subscribe to chatroom ${[chatRoomId]}`)
} else { } else {
@ -47,10 +40,9 @@ App.cable.subscriptions.create({
} }
}) })
// Receive information from index.html.erb
const acceptButton = document.getElementById('accept-button') const acceptButton = document.getElementById('accept-button')
acceptButton.addEventListener('click', event => { acceptButton.addEventListener('click', event => {
// event.preventDefault()
document.getElementById('chat-room-id').value = chatRoomId document.getElementById('chat-room-id').value = chatRoomId
}) })

View File

@ -0,0 +1,14 @@
const contactsVideo = document.getElementById("settings-video")
try {
const contactsStream = navigator.mediaDevices.getUserMedia({
audio: false,
video: true
}).then(stream => {
contactsVideo.srcObject = stream;
contactsVideo.muted = true;
})
} catch(e) {
console.error(e);
contactsVideo.innerHTML = "Unable to getUserMedia()";
}

View File

@ -1,7 +1,5 @@
// Broadcast Types // Broadcast Types
class Signaling {}
const JOIN_ROOM = "JOIN_ROOM"; const JOIN_ROOM = "JOIN_ROOM";
const EXCHANGE = "EXCHANGE"; const EXCHANGE = "EXCHANGE";
const REMOVE_USER = "REMOVE_USER"; const REMOVE_USER = "REMOVE_USER";
@ -16,12 +14,9 @@ let pcPeers = {}; // peer connection
let localstream; let localstream;
window.onload = () => { window.onload = () => {
// if (document.getElementById("current-user")) {
currentUser = document.getElementById("current-user").innerHTML; currentUser = document.getElementById("current-user").innerHTML;
console.log(currentUser)
localVideo = document.getElementById("local-video"); localVideo = document.getElementById("local-video");
remoteVideoContainer = document.getElementById("remote-video-container"); remoteVideoContainer = document.getElementById("remote-video-container");
// }
}; };
// Ice Credentials // Ice Credentials
@ -37,53 +32,21 @@ document.onreadystatechange = async () => {
}) })
localstream = stream; localstream = stream;
// if (localVideo) {
localVideo.srcObject = stream localVideo.srcObject = stream
localVideo.muted = true localVideo.muted = true
// }
} catch (e) { console.error(e); } } catch (e) { console.error(e); }
} }
}; };
// 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;
// }
// }
// });
// };
// if (document.getElementById('chatroom-hook')) {
const chatroomId = document.getElementById('chatroom-hook').dataset["chatroomId"] const chatroomId = document.getElementById('chatroom-hook').dataset["chatroomId"]
// }
const handleJoinSession = async () => { const handleJoinSession = async () => {
App['chatroom' + chatroomId] = await App.cable.subscriptions.create({ App['chatroom' + chatroomId] = await App.cable.subscriptions.create({
channel: "ChatRoomsChannel", channel: "ChatRoomsChannel",
room: chatroomId room: chatroomId
}, { }, {
connected: () => { connected: () => {
console.log(chatroomId)
broadcastData({ broadcastData({
type: JOIN_ROOM, type: JOIN_ROOM,
from: currentUser, from: currentUser,
@ -91,7 +54,6 @@ const handleJoinSession = async () => {
}); });
}, },
received: data => { received: data => {
console.log(data)
if (data.from === currentUser) return; if (data.from === currentUser) return;
switch (data.type) { switch (data.type) {
case JOIN_ROOM: case JOIN_ROOM:
@ -136,9 +98,6 @@ const removeUser = data => {
const broadcastData = data => { const broadcastData = data => {
if (data.type === EXCHANGE) {
console.log("yayyy")
}
fetch("chat_room_sessions", { fetch("chat_room_sessions", {
method: "POST", method: "POST",
body: JSON.stringify(data), body: JSON.stringify(data),
@ -220,7 +179,7 @@ const exchange = data => {
} }
if (data.sdp) { if (data.sdp) {
sdp = JSON.parse(data.sdp); const sdp = JSON.parse(data.sdp);
pc pc
.setRemoteDescription(new RTCSessionDescription(sdp)) .setRemoteDescription(new RTCSessionDescription(sdp))
.then(() => { .then(() => {
@ -242,3 +201,15 @@ const exchange = data => {
}; };
const logError = error => console.warn("Whoops! Error:", error); const logError = error => console.warn("Whoops! Error:", error);
const joinButton = document.getElementById("join-btn")
joinButton.addEventListener('click', event => {
handleJoinSession()
})
// WARNING: COMPLETELY HACKISH SOLUTION --> MUST INTRODUCE SOME SORT OF DELAY!
setTimeout(function() {
joinButton.click()
}, 5000);

View File

@ -1,27 +1,19 @@
<button onclick="handleJoinSession()" data-room="<%= @chat_room.id %>">Join Room</button> <div id="join-btn" data-room="<%= @chat_room.id %>"></div>
<!-- <div id="join-session" data-room="<%= @chat_room.id %>"> -->
<!-- <h1 style="color: white;">This is chatroom #<%= @chat_room.id %></h1> -->
<div id="chatroom-hook" data-chatroom-id='<%= @chat_room.id %>'></div> <div id="chatroom-hook" data-chatroom-id='<%= @chat_room.id %>'></div>
<!-- <button id="test-btn">Test Connection</button> -->
<div class="call-container"> <div class="call-container">
<div id="remote-video-container"> <div id="remote-video-container">
<div id="video_overlays"> <div id="video_overlays">
<video id="local-video" autoplay></video> <video id="local-video" autoplay muted></video>
</div> </div>
</div> </div>
</div> </div>
<div> <div><span id="current-user" class="text-color" style="display:none"><%= current_user.id %></span></div>
<span id="current-user" class="text-color" style="display:none"><%= current_user.id %></span>
</div>
<!-- <script>
const joinSession = document.getElementById("join-session")
joinSession.addEventListener('load', event => {
handleJoinSession()
})
</script> -->
<%= javascript_pack_tag 'chatrooms' %> <%= javascript_pack_tag 'chatrooms' %>
<%= javascript_pack_tag 'webrtc' %>

View File

@ -1,8 +1,23 @@
<div class="align-center"> <% params["action"] = "Add contact" %>
<h2>Add a new contact:</h2>
<%= form_for User.new, url: connections_path do |f| %>
<%= f.label :email, class: "email_label_color" %>:
<%= f.text_field :email %>
<%= f.submit %> <div class="center-screen">
<div class="align-center">
<div class="container">
<div class="row">
<div class="col-xs-offset-2 col-xs-8 col-xs-offset-2">
<h2>Enter an email address:</h2>
</div>
<%= simple_form_for User.new, url: connections_path, class: "input-group" do |f| %>
<div class="col-xs-offset-2 col-xs-8 col-xs-offset-2 ">
<div class="flex-inline">
<%= f.input_field :email, class: "form-control margin-right" %>
<div class="input-group-append">
<%= f.button :submit, value: "Add Contact" , class: "btn btn-primary" %>
</div>
</div>
</div>
<% end %> <% end %>
</div>
</div>
</div>
</div>

View File

@ -11,11 +11,19 @@
<%= f.input :password, <%= f.input :password,
required: false, required: false,
input_html: { autocomplete: "current-password" } %> input_html: { autocomplete: "current-password" } %>
<%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %> <div class="flex-inline space-between">
<%= f.label :remember_me %>
<label class="switch">
<%= f.input_field :enable_transcript, as: :boolean if devise_mapping.rememberable? %>
<span class="slider rounded"></span>
</label>
</div>
<%#= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
</div> </div>
<div class="form-actions"> <div class="form-actions">
<%= f.button :submit, "Log in", class: "login btn btn-primary" %> <%= f.button :submit, "Log in", class: "login btn btn-primary vertical-margin" %>
</div> </div>
<% end %> <% end %>

View File

@ -3,11 +3,11 @@
<% end -%> <% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %> <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%#= link_to "Sign up", new_registration_path(resource_name) %><!-- <br /> --> <%= link_to "Sign up", new_registration_path(resource_name) %><!-- <br /> -->
<% end -%> <% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br /> <%#= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%> <% end -%>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>

View File

@ -4,11 +4,17 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<%= favicon_link_tag 'favicon.ico' %> <!-- Need a favicon to change picture in title bar --> <%= favicon_link_tag 'favicon.ico' %> <!-- Need a favicon to change picture in title bar -->
<title>Polyglot</title> <title>Polyglot - Live Translation</title>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
<%= action_cable_meta_tag %> <%= action_cable_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all' %> <%= stylesheet_link_tag 'application', media: 'all' %>
<%#= stylesheet_pack_tag 'application', media: 'all' %> <!-- Uncomment if you import CSS in app/javascript/packs/application.js --> <%#= stylesheet_pack_tag 'application', media: 'all' %> <!-- Uncomment if you import CSS in app/javascript/packs/application.js -->
<meta property="og:title" content="<%= meta_title %>" />
<meta property="og:type" content="website" />
<meta property="og:url" content="<%= request.original_url %>" />
<meta property="og:image" content="<%= meta_image %>" />
<meta property="og:description" content="<%= meta_description %>" />
<meta property="og:site_name" content="<%= meta_title %>" />
</head> </head>
<body> <body>
<%= render 'shared/navbar' unless params["action"] == "home" || params["action"] == "new" || params["action"] == "call" %> <%= render 'shared/navbar' unless params["action"] == "home" || params["action"] == "new" || params["action"] == "call" %>
@ -16,6 +22,5 @@
<%= yield %> <%= yield %>
<%= javascript_include_tag 'application' %> <%= javascript_include_tag 'application' %>
<%= javascript_pack_tag 'application' %> <%= javascript_pack_tag 'application' %>
</body> </body>
</html> </html>

View File

@ -1,9 +1,3 @@
<%
def hello_world
puts "Hello World"
end
%>
<div class="card"> <div class="card">
<div class="info"> <div class="info">
<% if contact.photo.url.nil? %> <% if contact.photo.url.nil? %>
@ -12,17 +6,17 @@ end
<%= cl_image_tag contact.photo, class: "profile avatar dropdown-toggle img-circle", width:65%> <%= cl_image_tag contact.photo, class: "profile avatar dropdown-toggle img-circle", width:65%>
<% end %> <% end %>
<div class="text text-color"> <div class="text text-color">
<% if contact.nil? || contact.nil? %> <!-- REPLACE WITH FIRST NAME AND LAST NAME --> <% if contact.first_name.nil? || contact.last_name.nil? %>
<p><%= contact.email %></p> <p><%= contact.email %></p>
<% else %> <% else %>
<p><%= contact.email %></p> <p><%= contact.first_name %> <%= contact.last_name %></p>
<!-- <p><%#= contact.first_name %> <%#= contact.last_name %></p> -->
<% end %> <% end %>
<p class="darker">Last call: <%= Time.now %></p> <p class="darker">Last call: <%= Time.now %></p>
</div> </div>
</div> </div>
<div class="call" data-user-id="<%= contact.id %>"> <div class="call" data-user-id="<%= contact.id %>">
<%= link_to establish_call_path(contact.id), remote: true, id: "modalTrigger" do %> <!-- Calls establish_call in pages_controller -->
<%= link_to establish_call_path(contact.id), remote: true, class: "modalTrigger", data: {'user-id': contact.id } do %>
<i class="fas fa-phone"></i> <i class="fas fa-phone"></i>
<% end %> <% end %>
</div> </div>
@ -32,30 +26,30 @@ end
</div> </div>
<!-- Modal --> <!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal fade" id="myModal<%= contact.id %>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="vertical-alignment-helper"> <div class="vertical-alignment-helper">
<div class="modal-dialog vertical-align-center"> <div class="modal-dialog vertical-align-center">
<div class="modal-content modal-color"> <div class="modal-content modal-color">
<div class="modal-header"> <div class="modal-header">
<%= link_to "#", class:"pull-right", 'data-dismiss':"modal", 'data-target':"#myModal" do %> <%= link_to "#", class:"pull-right", 'data-dismiss':"modal", 'data-target':"#myModal#{contact.id}" do %>
<i class="fas fa-times-circle"></i> <i class="fas fa-times-circle"></i>
<% end %> <% end %>
<div class="container"> <div class="container">
<div class="modal-container"> <div class="modal-container modal-flex">
<img src="https://kitt.lewagon.com/placeholder/users/ssaunier" alt="" class="profile img-circle" width=150> <% if contact.photo.url.nil? %>
<img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png" class="avatar profile dropdown-toggle img-circle modal-picture" width=150>
<% else %>
<%= cl_image_tag contact.photo, class: "profile avatar dropdown-toggle img-circle modal-picture", width:150%>
<% end %>
<div class="modal-text"> <div class="modal-text">
<h4 class="modal-title" id="myModalLabel">Calling</h4> <h4 class="modal-title" id="myModalLabel">Calling</h4>
<h4> <h4>
<strong> <strong>
<!-- REPLACE WITH FIRST NAME AND LAST NAME --> <% if contact.first_name.nil? || contact.last_name.nil? %>
<% if contact.nil? || contact.nil? %>
<p><%= contact.email %></p> <p><%= contact.email %></p>
<% else %> <% else %>
<p><%= contact.email %></p> <p><%= contact.first_name %> <%= contact.last_name %></p>
<!-- <p><%#= contact.first_name %> <%#= contact.last_name %></p> -->
<% end %> <% end %>
</strong> </strong>
</h4> </h4>

View File

@ -1,28 +1,37 @@
<div id="contacts-page"></div>
<!-- CONTACTS PAGE -->
<div class="container"> <div class="container">
<div class="contacts-container text-color"> <div class="contacts-container text-color">
<div class="contacts half"> <div class="row">
<div class="col-xs-12 col-md-6">
<div class="contacts">
<div class="contacts-header"> <div class="contacts-header">
<h2>Contacts</h2> <h2>Contacts</h2>
<%= link_to add_contact_path do %>
<%= link_to new_connection_path do %>
<i class="fas fa-plus-square"></i> <i class="fas fa-plus-square"></i>
<% end %> <% end %>
</div> </div>
<div class="contacts-list">
<% current_user.contacts.each do |contact| %> <% current_user.contacts.each do |contact| %>
<%= render "pages/contact", contact: contact %> <%= render "pages/contact", contact: contact %>
<% end %> <% end %>
</div> </div>
<div class="video-feed half"> </div>
</div>
<div class="col-xs-12 col-md-6 hidden-xs hidden-sm">
<div class="video-feed">
<div class="video-content"> <div class="video-content">
<!-- <video id="contacts-video" autoplay=""></video> --> <video id="contacts-video" class="flex-video" autoplay=""></video>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- INFORMATION TO BE PASSED TO NOTIFICATIONS.JS -->
<div id="my-user-id" data-user-id="<%= current_user.id %>"></div> <div id="my-user-id" data-user-id="<%= current_user.id %>"></div>
<form action="/accept_call" method="post"> <form action="/accept_call" method="post">
@ -31,5 +40,6 @@
</form> </form>
<%= javascript_pack_tag 'notifications' %> <%= javascript_pack_tag 'notifications' %>
<%= javascript_pack_tag 'local_video' %>

View File

@ -8,3 +8,5 @@
<%= p.button :submit, class: "btn btn-primary" %> <%= p.button :submit, class: "btn btn-primary" %>
<% end %> <% end %>

View File

@ -1,12 +1,10 @@
<div class="polyglot-navbar"> <div class="polyglot-navbar">
<div class="logo"> <div class="logo"><%= link_to "Polyglot", contacts_path %></div>
Polyglot
</div>
<div class="right-align"> <div class="right-align hidden-xs hidden-sm">
<div class="links"> <div class="links">
<div class="active"><%= link_to "Dashboard", contacts_path %></div> <div id="contacts"><%= link_to "Contacts", contacts_path %></div>
<div><%= link_to "Settings", setting_path %></div> <div id="settings"><%= link_to "Settings", setting_path %></div>
</div> </div>
<div class="profile"> <div class="profile">
<% if current_user.nil? %> <% if current_user.nil? %>
@ -20,8 +18,7 @@
<%= cl_image_tag current_user.photo, class: "avatar dropdown-toggle img-circle"%> <%= cl_image_tag current_user.photo, class: "avatar dropdown-toggle img-circle"%>
<% end %> <% end %>
</div> </div>
<ul class="dropdown-menu dropdown-menu-right"> <ul class="dropdown-menu dropdown-menu-right polyglot-dropdown">
<!-- <li><a href="#">Profile</a></li> -->
<li><%= link_to "Profile", user_path(current_user) %></li> <li><%= link_to "Profile", user_path(current_user) %></li>
<li><%= link_to "Logout", destroy_user_session_path %></li> <li><%= link_to "Logout", destroy_user_session_path %></li>
</ul> </ul>
@ -29,4 +26,20 @@
<% end %> <% end %>
</div> </div>
</div> </div>
<div class="burger-menu hidden-md hidden-lg">
<div class="dropdown">
<i class="fa fa-bars dropdown-toggle" data-toggle="dropdown"></i>
<ul class="dropdown-menu dropdown-menu-right polyglot-dropdown">
<li><%= link_to "Contacts", contacts_path %></li>
<li><%= link_to "Settings", setting_path %></li>
<% if current_user.nil? %>
<li><%= link_to "Login", new_user_session_path %></li>
<% else %>
<li><%= link_to "Profile", user_path(current_user) %></li>
<li><%= link_to "Logout", destroy_user_session_path %></li>
<% end %>
</ul>
</div>
</div>
</div> </div>

View File

@ -7,25 +7,24 @@
<%= t.input :last_name %> <%= t.input :last_name %>
<%= t.input :password %> <%= t.input :password %>
<%= t.input :photo %> <%= t.input :photo %>
<div class="small-profile-pic hidden-md hidden-lg">
<%= t.submit :Save, class: "btn btn-primary save-btn form-control" %> <% if @user.photo.url.nil? %>
<p></p> <%= image_tag "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png"%>
<%= link_to "View my profile", user_path(@user), class: "btn btn-primary save-btn form-control" %> <% else %>
</div> <%= cl_image_tag current_user.photo%>
<% end %>
</div>
<div class="profile-pic"> <%= t.submit :Save, class: "btn btn-primary save-btn form-control" %>
<p></p>
<%= link_to "View my profile", user_path(@user), class: "btn btn-primary save-btn form-control" %>
</div>
<div class="profile-pic hidden-xs hidden-sm">
<% if @user.photo.url.nil? %> <% if @user.photo.url.nil? %>
<%= image_tag "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png"%> <%= image_tag "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png"%>
<% else %> <% else %>
<%= cl_image_tag current_user.photo%> <%= cl_image_tag current_user.photo%>
<% end %> <% end %>
<%#= t.input_field :photo, onchange: 'this.form.submit();' %>
<%#= t.input_field :photo, as: :hidden %>
</div> </div>
</div> </div>
<% end %> <% end %>
</div> </div>

View File

@ -1,158 +1,101 @@
<div class="profile-container"> <div id="settings-page"></div>
<%= simple_form_for(@user) do |t| %>
<div class="profile-form">
<div>
<div class="lign">
<div class="card"><%= t.input :language, collection: <% languages = [
[ "Afrikaans (South Africa)", "Amharic (Ethiopia)", "Armenian (Armenia)",
"Afrikaans (South Africa)", "Azerbaijani (Azerbaijan)", "Indonesian (Indonesia)", "Malay (Malaysia)",
"Amharic (Ethiopia)", "Bengali (Bangladesh)", "Bengali (India)", "Catalan (Spain)",
"Armenian (Armenia)", "Czech (Czech Republic)", "Danish (Denmark)", "German (Germany)",
"Azerbaijani (Azerbaijan)", "English (Australia)", "English (Canada)", "English (Ghana)",
"Indonesian (Indonesia)", "English (United Kingdom)", "English (India)", "English (Ireland)",
"Malay (Malaysia)", "English (Kenya)", "English (New Zealand)", "English (Nigeria)",
"Bengali (Bangladesh)", "English (Philippines)", "English (South Africa)", "English (Tanzania)",
"Bengali (India)", "English (United States)", "Spanish (Argentina)", "Spanish (Bolivia)",
"Catalan (Spain)", "Spanish (Chile)", "Spanish (Colombia)", "Spanish (Costa Rica)",
"Czech (Czech Republic)", "Spanish (Ecuador)", "Spanish (El Salvador)", "Spanish (Spain)",
"Danish (Denmark)", "Spanish (United States)", "Spanish (Guatemala)", "Spanish (Honduras)",
"German (Germany)", "Spanish (Mexico)", "Spanish (Nicaragua)", "Spanish (Panama)",
"English (Australia)", "Spanish (Paraguay)", "Spanish (Peru)", "Spanish (Puerto Rico)",
"English (Canada)", "Spanish (Dominican Republic)", "Spanish (Uruguay)", "Spanish (Venezuela)",
"English (Ghana)", "Basque (Spain)", "Filipino (Philippines)", "French (Canada)",
"English (United Kingdom)", "French (France)", "Galician (Spain)", "Georgian (Georgia)",
"English (India)", "Gujarati (India)", "Croatian (Croatia)", "Zulu (South Africa)",
"English (Ireland)", "Icelandic (Iceland)", "Italian (Italy)", "Javanese (Indonesia)",
"English (Kenya)", "Kannada (India)", "Khmer (Cambodia)", "Lao (Laos)",
"English (New Zealand)", "Latvian (Latvia)", "Lithuanian (Lithuania)", "Hungarian (Hungary)",
"English (Nigeria)", "Malayalam (India)", "Marathi (India)", "Dutch (Netherlands)",
"English (Philippines)", "Nepali (Nepal)", "Norwegian Bokmål (Norway)", "Polish (Poland)",
"English (South Africa)", "Portuguese (Brazil)", "Portuguese (Portugal)", "Romanian (Romania)",
"English (Tanzania)", "Sinhala (Sri Lanka)", "Slovak (Slovakia)", "Slovenian (Slovenia)",
"English (United States)", "Sundanese (Indonesia)", "Swahili (Tanzania)", "Swahili (Kenya)",
"Spanish (Argentina)", "Finnish (Finland)", "Swedish (Sweden)", "Tamil (India)",
"Spanish (Bolivia)", "Tamil (Singapore)", "Tamil (Sri Lanka)", "Tamil (Malaysia)",
"Spanish (Chile)", "Telugu (India)", "Vietnamese (Vietnam)", "Turkish (Turkey)",
"Spanish (Colombia)", "Urdu (Pakistan)", "Urdu (India)", "Greek (Greece)",
"Spanish (Costa Rica)", "Bulgarian (Bulgaria)", "Russian (Russia)", "Serbian (Serbia)",
"Spanish (Ecuador)", "Ukrainian (Ukraine)", "Hebrew (Israel)", "Arabic (Israel)",
"Spanish (El Salvador)", "Arabic (Jordan)", "Arabic (United Arab Emirates)", "Arabic (Bahrain)",
"Spanish (Spain)", "Arabic (Algeria)", "Arabic (Saudi Arabia)", "Arabic (Iraq)",
"Spanish (United States)", "Arabic (Kuwait)", "Arabic (Morocco)", "Arabic (Tunisia)",
"Spanish (Guatemala)", "Arabic (Oman)", "Arabic (Qatar)", "Arabic (Lebanon)",
"Spanish (Honduras)", "Arabic (Egypt)", "Persian (Iran)", "Hindi (India)",
"Spanish (Mexico)", "Thai (Thailand)", "Korean (South Korea)", "Chinese, Mandarin (Traditional, Taiwan)",
"Spanish (Nicaragua)", "Chinese, Cantonese (Traditional, Hong Kong)", "Japanese (Japan)",
"Spanish (Panama)",
"Spanish (Paraguay)",
"Spanish (Peru)",
"Spanish (Puerto Rico)",
"Spanish (Dominican Republic)",
"Spanish (Uruguay)",
"Spanish (Venezuela)",
"Basque (Spain)",
"Filipino (Philippines)",
"French (Canada)",
"French (France)",
"Galician (Spain)",
"Georgian (Georgia)",
"Gujarati (India)",
"Croatian (Croatia)",
"Zulu (South Africa)",
"Icelandic (Iceland)",
"Italian (Italy)",
"Javanese (Indonesia)",
"Kannada (India)",
"Khmer (Cambodia)",
"Lao (Laos)",
"Latvian (Latvia)",
"Lithuanian (Lithuania)",
"Hungarian (Hungary)",
"Malayalam (India)",
"Marathi (India)",
"Dutch (Netherlands)",
"Nepali (Nepal)",
"Norwegian Bokmål (Norway)",
"Polish (Poland)",
"Portuguese (Brazil)",
"Portuguese (Portugal)",
"Romanian (Romania)",
"Sinhala (Sri Lanka)",
"Slovak (Slovakia)",
"Slovenian (Slovenia)",
"Sundanese (Indonesia)",
"Swahili (Tanzania)",
"Swahili (Kenya)",
"Finnish (Finland)",
"Swedish (Sweden)",
"Tamil (India)",
"Tamil (Singapore)",
"Tamil (Sri Lanka)",
"Tamil (Malaysia)",
"Telugu (India)",
"Vietnamese (Vietnam)",
"Turkish (Turkey)",
"Urdu (Pakistan)",
"Urdu (India)",
"Greek (Greece)",
"Bulgarian (Bulgaria)",
"Russian (Russia)",
"Serbian (Serbia)",
"Ukrainian (Ukraine)",
"Hebrew (Israel)",
"Arabic (Israel)",
"Arabic (Jordan)",
"Arabic (United Arab Emirates)",
"Arabic (Bahrain)",
"Arabic (Algeria)",
"Arabic (Saudi Arabia)",
"Arabic (Iraq)",
"Arabic (Kuwait)",
"Arabic (Morocco)",
"Arabic (Tunisia)",
"Arabic (Oman)",
"Arabic (Qatar)",
"Arabic (Lebanon)",
"Arabic (Egypt)",
"Persian (Iran)",
"Hindi (India)",
"Thai (Thailand)",
"Korean (South Korea)",
"Chinese, Mandarin (Traditional, Taiwan)",
"Chinese, Cantonese (Traditional, Hong Kong)",
"Japanese (Japan)",
"Chinese, Mandarin (Simplified, Hong Kong)", "Chinese, Mandarin (Simplified, Hong Kong)",
"Chinese, Mandarin (Simplified, China)" ]%> "Chinese, Mandarin (Simplified, China)" ]%>
<% fonts = [
"Arial",
"Times New Roman",
"Calibri"
] %>
<div class="container">
<div class="contacts-container">
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="settings">
<h2>Settings</h2>
<div>
<%= simple_form_for(@user) do |t| %>
<div>
<div class="card card-form card-form-no-hover">
<%= t.label :language, class:'padding-right no-margin font-weight-normal' %>
<%= t.input_field :language, collection: languages.sort, class:'input-field-text-black input-dropdown form-control' %>
</div> </div>
<div class="card card-form card-form-no-hover">
<%= t.label :caption_font, class:'padding-right no-margin font-weight-normal' %>
<%= t.input_field :caption_font, collection: fonts.sort, class:'input-field-text-black input-dropdown form-control' %>
</div>
<div class="card card-form card-form-no-hover">
<%= t.label :caption_font_size, class:'padding-right no-margin font-weight-normal' %>
<%= t.input_field :caption_font_size, class:'input-field-text-black input-dropdown form-control' %>
</div>
<div class="card card-form card-form-no-hover">
<%= t.label :enable_transcript, class:'padding-right no-margin font-weight-normal' %>
<label class="switch">
<%= t.input_field :enable_transcript, class:'input-field-text-black' %>
<span class="slider round"></span>
</label>
</div> </div>
<div class="card"><%= t.input :caption_font %></div>
<div class="card"><%= t.input :caption_font_size %></div>
<div class="card"><%= t.input :enable_transcript %></div>
<%= link_to "Save", contacts_path, class: "btn btn-primary save-btn form-control" %> <%= link_to "Save", contacts_path, class: "btn btn-primary save-btn form-control" %>
<p></p> <p></p>
</div> </div>
<div class="profile-pic">
<% if @user.photo.url.nil? %>
<%= image_tag "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png"%>
<% else %>
<%= cl_image_tag current_user.photo%>
<% end %>
<%#= t.input_field :photo, onchange: 'this.form.submit();' %>
<%#= t.input_field :photo, as: :hidden %>
</div>
</div>
<% end %> <% end %>
</div> </div>
</div>
</div>
<div class="col-xs-12 col-md-6 hidden-xs hidden-sm">
<div class="video-feed">
<div class="video-content">
<video id="settings-video" class="flex-video" autoplay=""></video>
</div>
</div>
</div>
</div>
</div>
</div>
<%= javascript_pack_tag 'settings_video' %>

View File

@ -1,27 +1,28 @@
<div class="user-container"> <div class="user-container">
<div class="profile"> <div class="row">
<div class="profile-pic"> <div class="col-xs-12 col-md-3 vcenter">
<div class="profile-pic vertical-padding">
<% if @user.photo.url.nil? %> <% if @user.photo.url.nil? %>
<%= image_tag "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png", class: "img-circle"%> <%= image_tag "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png", class: "img-circle img-profile"%>
<% else %> <% else %>
<%= cl_image_tag @user.photo, class: "img-circle"%> <%= cl_image_tag @user.photo, class: "img-circle img-profile"%>
<% end %> <% end %>
</div> </div>
<div class="profile-text"> </div>
<div class="col-xs-12 col-md-4 vcenter">
<div class="profile-text vertical-padding">
<h1><%= @user.first_name %> <%= @user.last_name %></h1> <h1><%= @user.first_name %> <%= @user.last_name %></h1>
<h2 class="italics" ><%= @user.email %></h2> <h2 class="italics" ><%= @user.email %></h2>
</div> </div>
</div>
<div class="flex-end"> <div class="col-xs-12 col-md-4 vcenter">
<%= link_to "Edit Information", user_edit_path(@user), class: "btn btn-primary" %> <div class="flex-end vertical-padding">
<%= link_to "Delete Account", user_path(@user), class: "btn btn-danger", method: :delete, data: { <%= link_to "Edit Information", user_edit_path(@user), class: "btn btn-primary vertical-margin" %>
<%= link_to "Delete Account", user_path(@user), class: "btn btn-danger vertical-margin", method: :delete, data: {
confirm: "Are you sure?" confirm: "Are you sure?"
} %> } %>
</div> </div>
</div> </div>
</div> </div>
</div>

View File

@ -30,7 +30,7 @@ Rails.application.configure do
# config.assets.css_compressor = :sass # config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed. # Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false config.assets.compile = true
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb

View File

@ -0,0 +1 @@
DEFAULT_META = YAML.load_file(Rails.root.join("config/meta.yml"))

5
config/meta.yml Normal file
View File

@ -0,0 +1,5 @@
meta_product_name: "Product Name"
meta_title: "Polyglot - Live translation"
meta_description: "Translate your call live"
meta_image: "phone.jpg" # should exist in `app/assets/images/`
twitter_account: "@EthanFraenkel" # required for Twitter Cards

View File

@ -36,12 +36,11 @@ Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
get '/home', to: 'pages#home' get '/home', to: 'pages#home'
get '/users/:id', to: 'users#show', as: :user get '/users/:id', to: 'users#show', as: :user
get '/users/:id/edit', to: 'users#edit', as: :user_edit get '/users/:id/edit', to: 'users#edit', as: :user_edit
patch '/users/:id', to: 'users#update' patch '/users/:id', to: 'users#update'
delete '/users/:id', to: 'users#destroy' delete '/users/:id', to: 'users#destroy'
resources :connections, only: [:create, :new, :destroy] resources :connections, only: [:create, :destroy]
#get '/add_contact', to: 'connections#create' get '/add_contact', to: 'connections#new', as: :add_contact
end end

View File

@ -4,6 +4,7 @@
"dependencies": { "dependencies": {
"@rails/webpacker": "3.5", "@rails/webpacker": "3.5",
"actioncable": "^5.2.1", "actioncable": "^5.2.1",
"babel-plugin-transform-runtime": "^6.23.0",
"bootstrap": "3", "bootstrap": "3",
"jquery": "^3.3.1" "jquery": "^3.3.1"
}, },

View File

@ -1,67 +1,2 @@
<!DOCTYPE html> <h1>404 Error</h1>
<html> <p>Ethan, fix this</p>
<head>
<title>The page you were looking for doesn't exist (404)</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
.rails-default-error-page {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
margin: 0;
}
.rails-default-error-page div.dialog {
width: 95%;
max-width: 33em;
margin: 4em auto 0;
}
.rails-default-error-page div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #BBB;
border-top: #B00100 solid 4px;
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
padding: 7px 12% 0;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
.rails-default-error-page h1 {
font-size: 100%;
color: #730E15;
line-height: 1.5em;
}
.rails-default-error-page div.dialog > p {
margin: 0 0 1em;
padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
</style>
</head>
<body class="rails-default-error-page">
<!-- This file lives in public/404.html -->
<div class="dialog">
<div>
<h1>The page you were looking for doesn't exist.</h1>
<p>You may have mistyped the address or the page may have moved.</p>
</div>
<p>If you are the application owner check the logs for more information.</p>
</div>
</body>
</html>

View File

@ -1,67 +1,2 @@
<!DOCTYPE html> <h1>422 Error</h1>
<html> <p>Ethan, fix this</p>
<head>
<title>The change you wanted was rejected (422)</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
.rails-default-error-page {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
margin: 0;
}
.rails-default-error-page div.dialog {
width: 95%;
max-width: 33em;
margin: 4em auto 0;
}
.rails-default-error-page div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #BBB;
border-top: #B00100 solid 4px;
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
padding: 7px 12% 0;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
.rails-default-error-page h1 {
font-size: 100%;
color: #730E15;
line-height: 1.5em;
}
.rails-default-error-page div.dialog > p {
margin: 0 0 1em;
padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
</style>
</head>
<body class="rails-default-error-page">
<!-- This file lives in public/422.html -->
<div class="dialog">
<div>
<h1>The change you wanted was rejected.</h1>
<p>Maybe you tried to change something you didn't have access to.</p>
</div>
<p>If you are the application owner check the logs for more information.</p>
</div>
</body>
</html>

View File

@ -1,66 +1,2 @@
<!DOCTYPE html> <h1>500 Error</h1>
<html> <p>Ethan, fix this</p>
<head>
<title>We're sorry, but something went wrong (500)</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
.rails-default-error-page {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
margin: 0;
}
.rails-default-error-page div.dialog {
width: 95%;
max-width: 33em;
margin: 4em auto 0;
}
.rails-default-error-page div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #BBB;
border-top: #B00100 solid 4px;
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
padding: 7px 12% 0;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
.rails-default-error-page h1 {
font-size: 100%;
color: #730E15;
line-height: 1.5em;
}
.rails-default-error-page div.dialog > p {
margin: 0 0 1em;
padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
</style>
</head>
<body class="rails-default-error-page">
<!-- This file lives in public/500.html -->
<div class="dialog">
<div>
<h1>We're sorry, but something went wrong.</h1>
</div>
<p>If you are the application owner check the logs for more information.</p>
</div>
</body>
</html>

View File

@ -680,6 +680,12 @@ babel-plugin-transform-regenerator@^6.22.0:
dependencies: dependencies:
regenerator-transform "^0.10.0" regenerator-transform "^0.10.0"
babel-plugin-transform-runtime@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee"
dependencies:
babel-runtime "^6.22.0"
babel-plugin-transform-strict-mode@^6.24.1: babel-plugin-transform-strict-mode@^6.24.1:
version "6.24.1" version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"