How do I create chat rooms in Firechat? - javascript

I am using Firechat and I am able to successfully initiate the chat window. I am using Firebase custom authentication and I can login without any problem. However, I now try to create a new chat room and then enter it. Based on the Firechat documentation I did the following:
<!doctype html>
<html>
<head>
<title>Test</title>
<meta charset="UTF-8" />
<script src='https://cdn.firebase.com/js/client/2.0.2/firebase.js'></script>
<link rel='stylesheet' href='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.css' />
<script src='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.js'></script>
</head>
<body>
<script type='text/javascript'>
var fireBase = new Firebase("https://XXXXXXXXX.firebaseio.com/");
function initChat(authData) {
var Firechat = new FirechatUI(fireBase, document.getElementById('firechat'));
Firechat.setUser(authData.uid, "Username");
Firechat.createRoom("Test chat room", "public");
}
fireBase.authWithCustomToken("UNIQUE_TOKEN", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Login successful", authData);
initChat(authData);
}
});
</script>
<div id='firechat'>
</div>
</body>
</html>
In the javascript console I can see that login is successful:
Login successful Object { auth: Object, expires: XXXXXXXXX, token: "XXXXXXXX…", uid: "XXXXXX", provider: "custom" }
But the createRoom function is not found:
TypeError: Firechat.createRoom is not a function
Any idea what is going wrong here?

From the docs:
Firechat.createRoom(roomName, roomType, callback(roomId))
Creates a new room with the given name (string) and type (string - public or private) and invokes the callback with the room ID on completion.
It would seem that you do not have a callback.
Firechat.prototype.createRoom = function(roomName, roomType, callback) {
var self = this,
newRoomRef = this._roomRef.push();
var newRoom = {
id: newRoomRef.name(),
name: roomName,
type: roomType || 'public',
createdByUserId: this._userId,
createdAt: Firebase.ServerValue.TIMESTAMP
};
if (roomType === 'private') {
newRoom.authorizedUsers = {};
newRoom.authorizedUsers[this._userId] = true;
}
newRoomRef.set(newRoom, function(error) {
if (!error) {
self.enterRoom(newRoomRef.name());
}
if (callback) {
callback(newRoomRef.name());
}
});
};
Source: https://firechat.firebaseapp.com/docs/firechat.html

So it turns out that there are two classes (is that the right word) used in the Firechat javascript plugin:
var chat = new FirechatUI
var chat = new Firechat
Because they seem so similar I did not notice the difference. Nowhere in the documentation have I been able to find details of the FirechatUI instance (even though this code is recommended on the github readme).
So anyway, the thing is that new FirechatUI loads the actual UI for the chat. new Firechat loads the API that allows you to talk to the chat plugin (but NOT to the UI). This is an important difference. The documentation found here only relates to the API so if you initiate a new Firechat instance. However, the trick is to get the UI up and running and then interact with it directly (doing things like creating new rooms or entering rooms). I have honestly not found out how to do this the official/recommended way. The only thing I've been able to come up with is a hack. It's ugly, but it works. The code below includes functionality to create a new chat room (using Firechat) and to open a particular chatroom in the UI (that bit is hacked as I couldn't find a way to interact with the UI directly).
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
<!-- jQuery -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script>
<!-- Firebase -->
<script src='https://cdn.firebase.com/js/client/2.1.0/firebase.js'></script>
<!-- Firechat -->
<link rel='stylesheet' href='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.css' />
<script src='https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.js'></script>
<!-- This plugin here: https://gist.github.com/buu700/4200601 -->
<script type="text/javascript" src="js/arrive.js"></script>
<style type="text/css">
#firechat{width:400px}
</style>
</head>
<body>
<h1>Test</h1>
<script type='text/javascript'>
var fireBase = new Firebase("https://XXXXXX.firebaseio.com/");
function roomChatSetup(authData) {
var chat = new Firechat(fireBase);
chat.setUser(authData.uid, "My User Name", function(user) {
console.log("Creating chatroom...");
chat.createRoom("New Chatroom Name", "public", function(roomId) {
console.log("Created room "+roomId);
});
$("#firechat").html("<div class='alert alert-success'>Your chatroom has been set up. Refresh to view</div>");
});
}
function initChat(authData) {
var chatUI = new FirechatUI(fireBase, document.getElementById('firechat'));
chatUI.setUser(authData.uid, "My User Name");
console.log("Simulating clicks...");
$("#firechat-tab-content div.tab-pane").waitUntilExists(function(){
console.log("Close all other tabs by simulating clicking the X button");
$("#firechat-tab-content div.tab-pane:not(#XXXXXXXXX) a.close").click(); // XXXXX should have the chatroom name of the one you want to open
});
$("#firechat-btn-rooms").waitUntilExists(function(){
$("#firechat-btn-rooms").click();
console.log("Open submenu to load all possible rooms");
});
$("li[data-room-id='XXXXXXXXXXXXX']").waitUntilExists(function(){
$("li[data-room-id='XXXXXXXXXX'] a").click();
console.log("Simulating clicking on chatroom XXXXXXXXXXXXXX");
});
}
fireBase.authWithCustomToken("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Login successful", authData);
// Here you can use a programming language to decide. If you already have a
// chatroom, run initChat. If you don't, run createRoom. I haven't been
// able to run them both at the same time.
initChat(authData);
// or:
roomChatSetup(authData);
}
});
</script>
<div id="firechat"></div>
</body>
</html>

The FirechatUI object is separate from the Firechat object. FirechatUI does not have the same methods that Firechat does.
In order to get the associated Firechat object from a FirechatUI object you can do the following:
let chatUI = new FirechatUI(chatRef, document.getElementById("firechat-wrapper"));
let chat = chatUI._chat;
You can then do any normal Firechat operations without any issues.
chat.setUser(user.uid, firstName, function(user) {
chat.resumeSession();
});
Please keep in mind that the _chat element is not really supposed to be used (as you can tell from the naming convention), but since FirechatUI does not properly expose enough functionality this is probably the cleanest way to do it.

Related

Silence net::ERR_CONNECTION_REFUSED

Connecting to a non-existent web socket server results in loud errors being logged to the console, usually to the tune of ... net::ERR_CONNECTION_REFUSED.
Anyone have an idea for a hackaround to silence this output? XMLHttpRequest won't work since it yields the same verbose error output if the server is not reachable.
The goal here is to test if the server is available, if it is then connect to it, otherwise use a fallback, and to do this without spamming the console with error output.
Chrome itself is emitting these messages, and there is no way to block them. This is a function of how chrome was built; whenever a ResourceFetcher object attempts to fetch a resource, its response is passed back to its context, and if there's an error, the browser prints it to the console - see here.
Similar question can be found here.
If you'd like, you can use a chrome console filter as this question discusses to block these errors in your console, but there is no way to programmatically block the messages.
I don't know why do you want to prevent this error output. I guess you just want to get rid of them when debugging. So I provide a work around here may be just useful for debugging.
Live demo: http://blackmiaool.com/soa/43012334/boot.html
How to use it?
Open the demo page, click the "boot" button, it will open a new tab. Click the "test" button in the new tab and check the result below. If you want to get a positive result, change the url to wss://echo.websocket.org.
Why?
By using post message, we can make browser tabs communicate with each other. So we can move those error output to a tab that we don't concern.
P.S. You can refresh the target page freely without loosing the connection between it and boot page.
P.P.S You can also use storage event to achieve this.
boot.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>boot page</title>
</head>
<body>
<button onclick="boot()">boot</button>
<p>BTW, you can boot the page without the button if you are willing to allow the "pop-up"</p>
<script>
var targetWindow;
function init() {
targetWindow
}
function boot() {
targetWindow = window.open("target.html");
}
boot();
window.addEventListener('message', function(e) {
var msg = e.data;
var {
action,
url,
origin,
} = msg;
if (action === "testUrl") {
let ws = new WebSocket(url);
ws.addEventListener("error", function() {
targetWindow.postMessage({
action: "urlResult",
url,
data: false,
}, origin);
ws.close();
});
ws.addEventListener("open", function() {
targetWindow.postMessage({
action: "urlResult",
url,
data: true,
}, origin);
ws.close();
});
}
});
</script>
</body>
</html>
target.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>target page</title>
</head>
<body>
<h4>input the url you want to test:</h4>
<textarea type="text" id="input" style="width:300px;height:100px;">
</textarea>
<br>
<div>try <span style="color:red">wss://echo.websocket.org</span> for success result(may be slow)</div>
<button onclick="test()">test</button>
<div id="output"></div>
<script>
var origin = location.origin;
var testUrl = origin.replace(/^https?/, "ws") + "/abcdef"; //not available of course
document.querySelector("#input").value = testUrl;
function output(val) {
document.querySelector("#output").textContent = val;
}
function test() {
if (window.opener) {
window.opener.postMessage({
action: "testUrl",
url: document.querySelector("#input").value,
origin,
}, origin);
} else {
alert("opener is not available");
}
}
window.addEventListener('message', function(e) {
var msg = e.data;
if (msg.action === "urlResult") {
output(`test ${msg.url} result: ${msg.data}`);
}
});
</script>
</body>
</html>

Face to face video chat using openTok (tokbox)

I build a kind of a social network where the users can chat with each other.
Only private chats, not rooms or groups or anything like this.
I want to to add a feature to the chat - video chat.
And I find openTok (tokbox).
I read alot from thier manual but I can't make it work.
I started in something simple.
I opend in two different computers url with this code:
<html>
<head>
<script src="http://static.opentok.com/webrtc/v2.0/js/TB.min.js" ></script>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<script type="text/javascript">
var apiKey = **myApiKey**;
var sessionId = **sessionId **;
var token = **token**;
function sessionConnectedHandler (event) {
session.publish( publisher );
subscribeToStreams(event.streams);
}
function subscribeToStreams(streams) {
for (var i = 0; i < streams.length; i++) {
var stream = streams[i];
if (stream.connection.connectionId
!= session.connection.connectionId) {
session.subscribe(stream);
}
}
}
function streamCreatedHandler(event) {
subscribeToStreams(event.streams);
}
var publisher = TB.initPublisher(apiKey);
var session = TB.initSession(sessionId);
session.connect(apiKey, token);
session.addEventListener("sessionConnected",
sessionConnectedHandler);
session.addEventListener("streamCreated",
streamCreatedHandler);
</script>
</head>
<body>
</body>
</html>
Of course I changed myApiKey, sessionId, token to my details from my account.
The problem is that In every page I can see myself, buy the partner window doesn't stop loading...
What can I do?
Thanks
In your sessionConnectedHandler(), you have to remove publisher parameter, then it works fine... Somewhat look like this:
function sessionConnectedHandler(event) {
subscribeToStreams(event.streams);
session.publish();
}

How to load a db context in another Html page using YDN-DB?

I've loaded all my data on the very first page:
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="/Scripts/modernizr-1.7.min.js" type="text/javascript"></script>
<script src="/Scripts/ydn.db-jquery-0.7.5.js" type="text/javascript"></script>
<script src="/Scripts/jquery.mousewheel.js"></script>
...
var schema = {
stores: [{
name: 'products',
keyPath: 'cdProduto',
autoIncrement: false,
indexes: [
{
keyPath: 'cdCategoria'
}, {
keyPath: 'dtUltimaAtualizacao'
}]
}]
};
var db = new ydn.db.Storage('db-test', schema);
db.clear().done(function (num) {
db.add('products', [<%=jsonProducts%>]);
});
The <%=jsonProducts%> prints some json from C# back-end.
I can load the information like this, it works:
db.get('products', '2').always(function (record) {...
After, in the same browser and session, when I try to load my second page (/catalogo.html), then load the same product with the '2' key, like this:
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="/Scripts/modernizr-1.7.min.js" type="text/javascript"></script>
<script src="/Scripts/ydn.db-jquery-0.7.5.js" type="text/javascript"></script>
<script src="/Scripts/jquery.mousewheel.js"></script>
...
var db = new ydn.db.Storage('db-test');
db.get('products', '2').done(function (value) {
console.log(value);
});
It returns 'undefined' on the console. I have no clues.
Besides, im using html cache manifest on both pages
<html manifest="/home/manifest">
and testing under local server, acessing with localhost and port 60873, for example.
Am I missing something? Ain't that the right way to open an existing YDN-DB?
Thanks!
You are not missing anything and it should work.
You should check indexeddb content on resource panel of dev console.
You should initialize in second page /catalogo.html exactly as in first page, i.e,
var db = new ydn.db.Storage('db-test', schema);
Changing schema my drop some tables. Such data lost occur when database constraint are not met. It could be triggered by the library or browser itself.
It is a good practice to check database connection before using as follow:
db.addEventListener('ready', function (event) {
var is_updated = event.getVersion() != event.getOldVersion();
if (is_updated) {
console.log('database connected with new schema');
} else if (isNaN(event.getOldVersion())) {
console.log('new database created');
} else {
console.log('existing database connected');
}
// heavy database operations should start from this.
});

Play Framework 2.1 websockets in Chrome

I can't seem to get websocket communication to work in the Play Framework version 2.1.
I created a simple test that does nothing but send messages back and forth with a push of a button. All the code for it is below. But nothing shows up except for the button.
Has anybody seen this problem or can someone tell me what I may be doing wrong in the code below?
I am using the latest version of Chrome.
Here is my simple setup.
In Application.java
public static Result index() {
return ok(index.render());
}
public static WebSocket<String> sockHandler() {
return new WebSocket<String>() {
// called when the websocket is established
public void onReady(WebSocket.In<String> in,
WebSocket.Out<String> out) {
// register a callback for processing instream events
in.onMessage(new Callback<String>() {
public void invoke(String event) {
System.out.println(event);
}
});
// write out a greeting
out.write("I'm contacting you regarding your recent websocket.");
}
};
}
In Routes File
GET / controllers.Application.index()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
GET /greeter controllers.Application.sockHandler()
In Index.Scala.html
#main(null) {
<div class="greeting"></div>
<button class="send">Send</button>
<script type="text/javascript" charset="utf-8">
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var sock = new WS("#routes.Application.sockHandler()")
sock.onmessage = function(event) {
$('.greeting').append(event.data)
}
$('button.send').click(function() {
sock.send("I'm sending a message now.")
});
})
</script>
}
In Main.scala.html
#(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>#title</title>
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.at("images/favicon.png")">
<script src="#routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
</head>
<body>
#content
</body>
The problem is in
var sock = new WS("#routes.Application.sockHandler()")
you have to specify the protocol and the complete url in the format: ws://localhost:9000/greeter.
Check this question to do it in javascript: How to construct a WebSocket URI relative to the page URI?
you can use a Route's webSocketURL() method to retrieve a url that can be passed to a WebSocket's constructor. Here's an example from Play's websocket-chat sample code:
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var chatSocket = new WS("#routes.Application.chat(username).webSocketURL()")
var sendMessage = function() {
chatSocket.send(JSON.stringify(
{text: $("#talk").val()}
))
$("#talk").val('')
}
// ...
So in your code you can use something like
var sock = new WS("#routes.Application.sockHandler().webSocketURL()");
Personally I don't like intermingling interpolated code with JS, since I think that any code executing on the client should only be concerned with the state of the client, and not the server (not to mention it makes refactoring the script out into an external file impossible), so I tend to do something like this:
<div class="container app-container"
data-ws-uri="#routes.Application.WSUri.webSocketURL()">
.......
</div>
Then in my JS I can just do something like
var sock = new WS(document.querySelector(".app-container").dataset.wsUri);
// ....

how to create contact in iphone using phonegap

I am new to iPhone development and phonegap also. Now i want to create contact in iPhone using phonegap. I got the link to create contact in iPhone with coding. But there one HTML coding with JavaScript. But when i run the coding the simulator and device show's only the HTML tag contents.
I followed this below link only:
"http://docs.phonegap.com/en/2.0.0/cordova_contacts_contacts.md.html#Contacts"
I have attach the coding and Screen Short:
<!DOCTYPE html>
<html>
<head>
<title>Contact Example</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Cordova is ready
//
function onDeviceReady() {
var myContact = navigator.contacts.create({"displayName": "Test User"});
myContact.note = "This contact has a note.";
navigator.contacts.save(myContact); //HERE
console.log("The contact, " + myContact.displayName + ", note: " + myContact.note);
}
</script>
</head>
<body>
<h1>Example</h1>
<p>Create Contact</p>
</body>
</html>
Screen Short:
Please help me to solve the issue. I have followed all the instruction from that above link. But I didn't get the solution. Thanks in advance.
You need to save your contact.
The documentation states :
contacts.create is a synchronous function that returns a new Contact object.
This method does not persist the Contact object to the device contacts database. To persist the Contact object to the device, invoke the Contact.save method.
function onDeviceReady() {
var myContact = navigator.contacts.create({"displayName": "Test User"});
myContact.note = "This contact has a note.";
navigator.contacts.save(myContact); //HERE
console.log("The contact, " + myContact.displayName + ", note: " + myContact.note);
}
var myContact = navigator.contacts.create({"displayName": "Test User"});
Full Example
<!DOCTYPE html>
<html>
<head>
<title>Contact Example</title>
<script type="text/javascript" charset="utf-8" src="phonegap-1.0.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for PhoneGap to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
//
function onDeviceReady() {
try {
var contact = navigator.contacts.create();
contact.displayName = "Plumber";
contact.nickname = "Plumber"; //specify both to support all devices
// populate some fields
var name = new ContactName();
name.givenName = "Jane";
name.familyName = "Doe";
contact.name = name;
// save to device
contact.save(function(){
alert("Save Success");
},function(){
alert("Error...");
});
} catch(_err) {
alert(_err)
}
}
</script>
</head>
<body>
<h1>Example</h1>
<p>Create Contact</p>
</body>
</html>
OR You can find more option for contact api.
I think you have not read document. i have also edited my answers please check once again.
Description :
contacts.create is a synchronous function that returns a new Contact object.
This method does not persist the Contact object to the device contacts database. To persist the Contact object to the device, invoke the Contact.save method.
http://docs.phonegap.com/en/1.0.0/phonegap_contacts_contacts.md.html#contacts.create

Categories