Skip to content

Instantly share code, notes, and snippets.

@afalchi82
Created May 18, 2016 17:15
Show Gist options
  • Save afalchi82/a4fa02201ecb77ceafbf21721d596559 to your computer and use it in GitHub Desktop.
Save afalchi82/a4fa02201ecb77ceafbf21721d596559 to your computer and use it in GitHub Desktop.
Vocal chatroom
section
.container
.row
.col-xs-12
h1 Vocal Chatroom <i class="fa fa-microphone" aria-hidden="true"></i>
small speak in your browser's voice (<strong>turn on volume <i class="fa fa-smile-o" aria-hidden="true"></i></strong> )
// h4 CHAT ID:
strong {{chat_id}}
.row(ng-show="usernameIsSet")
.col-xs-12
ul.users
li(ng-repeat="user in users")
.avatar
.img(style="background-image:url({{user.picture}})", ng-class="{speak: isSpeaking && isSpeakingUser === user.name}")
p {{user.name}}
.row(ng-show="!usernameIsSet")
.col-xs-12
.avatar(ng-class="user.name")
.img(style="background-image:url({{user.picture}}); margin-left:auto; margin-right:auto; width:120px; height: 120px;", ng-class="{speak: isSpeaking && isSpeakingUser === user.name}")
p {{user.name}}
.row
.col-xs-12
.well(ng-show="!usernameIsSet")
form(ng-submit="setUser()")
.form-group
label
i.fa.fa-user
| Username
input.form-control(type="text", novalidate, required, maxlength="10", ng-model="user.name", placeholder="Choose a username", ng-disabled="usernameIsSet")
.form-group(ng-show="!usernameIsSet")
label
i.fa.fa-picture-o
| Profile picture URL
input.form-control(type="text", novalidate, ng-model="user.picture", placeholder="picture", ng-disabled="usernameIsSet")
.form-group
button.btn.btn-success.btn-lg(type="submit", ng-if="!usernameIsSet")
| Start!
.row(ng-show="usernameIsSet")
.col-xs-12
form(ng-submit="submit()")
.form-group
input.form-control(type="text", novalidate, required, maxlength="50", placeholder="Your message" ng-model="user.message")
.form-group
// button.btn.btn-primary(type="submit")
| Send message
.row
.col-xs-12
// Articoli
article.media(ng-repeat="item in chatMessages") {{item.text}}
//button.btn.btn-sm.btn-danger(ng-click="clear()") remove
//
.row
.col-xs-12
pre
| {{users | json}}
//
.row
.col-xs-12
a(href="https://twitter.com/share", class="twitter-share-button", data-via="afalchi82") Tweet
script
| !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
.row
.col-xs-12
a(href="https://m1sc.firebaseio.com/chat", target="_blank") Inspect this firebase
console.clear();
angular.module('myApp', ['firebase'])
.run(function($rootScope, chatMessages, speechSynt, users) {
var defaultMessage = 'Eeehy bella bimba, la vuoi una caramella?';
var vm = $rootScope;
vm.text = '';
vm.chatMessages = chatMessages;
vm.chatMessagesArr = chatMessages.arr;
vm.users = users;
vm.chat_id = chatMessages.id;
vm.isSpeaking = false;
vm.user = {
name: '',
message: '',
picture: 'https://cdn.pbrd.co/images/P93JuF9.png'
};
vm.setUser = function () {
vm.usernameIsSet = true;
vm.users.$add(vm.user);
};
vm.submit = function () {
vm.chatMessagesArr.$add({
user: vm.user.name,
text: vm.user.message,
date: Date.now()
});
vm.user.message = '';
};
vm.clear = function() {
vm.chatMessages.ref.set('');
};
speechSynt.speech.onend = function () {
vm.$applyAsync(function () {
vm.isSpeaking = false;
});
};
chatMessages.ref.limitToLast(1).on('child_added', function(childSnapshot, prevChildKey) {
speechSynt.talk(childSnapshot.val().text || defaultMessage);
console.log(childSnapshot.name());
vm.$applyAsync(function () {
vm.isSpeaking = true;
vm.isSpeakingUser = childSnapshot.val().user;
});
});
})
/* ---------------------------------------------------------
Services
----------------------------------------------------------*/
.factory('speechSynt', function() {
var voices = window.speechSynthesis.getVoices(),
speech = new SpeechSynthesisUtterance();
speech.voice = voices[2]; // Note: some voices don't support altering params
speech.voice = speechSynthesis.getVoices().filter(function(voice) {return voice.name == 'Whisper';})[0]
speech.voiceURI = 'native';
speech.volume = .8; // 0 to 1
speech.rate = 1; // 0.1 to 10
speech.pitch = 1; //0 to 2
speech.lang = 'it-IT';
// speech.lang = 'en-US';
return {
speech: speech,
talk: function ($m) {
speech.text = $m;
speechSynthesis.speak(speech);
}
};
})
.factory('users', function($firebaseArray){
var ref = new Firebase("https://m1sc.firebaseio.com/chat/users");
return $firebaseArray(ref);
})
.factory("chatMessages", function($firebaseArray, $firebaseObject) {
//var timestamp = Date.now();
//var ref = new Firebase("https://m1sc.firebaseio.com/chat/chat_" + timestamp);
var ref = new Firebase("https://m1sc.firebaseio.com/chat/messages");
// ref.set('');
// this uses AngularFire to create the synchronized array
return {
//id: timestamp,
ref: ref,
arr: $firebaseArray(ref),
obj: $firebaseObject(ref)
};
})
;
/* --------------------------------------------------------------- */
// Manual bootstrapping Angular to check browser speech support first
/* --------------------------------------------------------------- */
if ('speechSynthesis' in window) {
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
} else {
console.log('else');
document.body.innerHTML = '<i class="fa fa-chrome" aria-hidden="true"></i> Please use Google Chrome.';
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://code.angularjs.org/1.3.15/angular.min.js"></script>
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.2.0/angularfire.min.js"></script>
@import url(https://fonts.googleapis.com/css?family=Work+Sans:400,300,500);
$accent: #F12E8F;
body {
font-family: 'Work Sans', sans-serif;
padding: 50px 0;
text-align: center;
}
.container {
max-width: 480px;
}
h1 {
font-weight: 800;
font-size: 45px;
margin-bottom: 30px;
.fa {
color: $accent;
}
small {
text-transform: uppercase;
font-size: 12px;
display: block;
}
}
form {
margin: 0 0 20px;
input {text-align: center;}
}
.avatar {
margin-bottom: 30px;
text-align: center;
text-transform: capitalize;
.img {
background-size: cover;
width: 60px;
height: 60px;
border-radius: 60px;
margin: 30px 10px 10px;
transition: all .5s linear;
transform: scale(1);
}
}
.users {
margin: 0;
padding: 0;
text-align: center;
li {
display:inline-block;
list-style:none;
}
}
.speak {
animation-name: speakAnim;
animation-duration: .1s;
animation-timing-function: ease-out;
animation-iteration-count: infinite;
animation-direction: alternate;
}
@keyframes speakAnim {
from {
transform: scale(1.2);
box-shadow: 0 0 0px $accent;
}
to {
transform: scale(1.22);
box-shadow: 0 0 5px $accent;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.1/animate.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment