Skip to content

Instantly share code, notes, and snippets.

@gordienoye
Last active August 29, 2015 13:56
Show Gist options
  • Save gordienoye/8793241 to your computer and use it in GitHub Desktop.
Save gordienoye/8793241 to your computer and use it in GitHub Desktop.
<html>
<head>
<title>Query Chat</title>
<script src="https://cdn.goinstant.net/v1/platform.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- This application really needs to look a little better -->
<style type="text/css">
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.container {
max-width: 800px;
margin: 50px auto;
}
#messages {
margin-top: 20px;
padding: 0;
list-style: none;
border: 1px solid #ccc;
border-style: none none solid none;
}
#messages li {
position: relative;
border-top: 1px solid #ccc;
padding: 15px;
background: #f7f7f7;
font-size: .9em;
}
#messages li button {
position: absolute;
right: 15px;
top: 11px;
}
</style>
</head>
<body>
<div class="container">
<h2>Chat Messages</h2>
Your Name: <input type="text" name="user-name" />
Your Message: <input type="text" name="new-message" />
<ul id="messages">
<!-- chat messages will be inserted here -->
</ul>
</div>
<script>
/*
* Sample item might look like:
* item = {
* name: "id-143da6a9715-000", // generated by GoInstant when using Key#add
* value: {
* text: "Hello",
* timestamp: 1390938801050,
* user: "Henry Morton Stanley"
* }
* };
*
* Sample context might look like:
* context = {
* position: {
* current: 4, // the current position in the Query results (add & update)
* previous: null // the previous position in the Query results (remove & update)
* },
* events: {
* total: 2, // the total number of events caused by a single Key change
* current: 2 // this event's position in the events caused by a Key change
* },
* event: 'add', // event type ('add', 'remove', or 'update')
* child: 'keyName' // the name of the child key in the Query results
* };
*
*/
function updateChatMessage(item, context) {
var displayElement = '<li id="' + item.name + '">' +
'[' + item.value.timestamp + '] ' +
'<span style="color:red">' + item.value.user + ' says: </span>' +
item.value.text +
'<button>&times;</button>' +
'</li>';
var currChildSelector = '#messages li:eq(' + context.position.current + ')';
var prevChildSelector = '#messages li:eq(' + context.position.previous + ')';
prevChildSelector = '#' + item.name;
var numChildren = $('#messages').children('li').length;
switch (context.event) {
case 'add':
if (context.position.current === numChildren) {
// if the add position is one more than the number of items in the list
// then we will append the item to the end.
$('#messages').append(displayElement);
} else if (context.position.current < numChildren) {
// if the add position is within the list of elements we add the item before
// the existing item.
$(displayElement).insertBefore(currChildSelector);
} else {
// this should never happen if nothing else touches the #messages list.
console.log("Received an `add` event for a list item could not exist");
}
break;
case 'update':
$(currChildSelector).replaceWith(displayElement);
break;
case 'remove':
$(prevChildSelector).remove();
break;
};
}
$(document).ready(function () {
// TODO: The 'QueryChat' application should be created in your GoInstant
// dashboard and the URL updated appropriately.
var url = 'https://goinstant.net/<YOURACCOUNT>/<YOURAPPLICATION>';
goinstant.connect(url, function (err, connection, lobby) {
if (err) {
throw err; // Could not connect to GoInstant
}
var chatMessagesKey = lobby.key('chatMessages');
var filter = { };
var sort = { 'timestamp': 'desc' };
var limit = 10;
var options = { sort: sort, limit: limit };
var chatMessagesQuery = chatMessagesKey.query(filter, options);
chatMessagesQuery.on("add", function(item, context) {
updateChatMessage(item, context);
});
chatMessagesQuery.on("remove", function(item, context) {
updateChatMessage(item, context);
});
chatMessagesQuery.on("update", function(item, context) {
updateChatMessage(item, context);
});
chatMessagesQuery.execute(function(err, results) {
if (err) {
throw err; // Invalid query
}
});
// add a new message when the user hits the <Enter> key.
var newMessage = $('input[name="new-message"]');
newMessage.keypress(function(e) {
var messageText = newMessage.val();
if (e.which === 13 && messageText) {
var currUser = $('input[name="user-name"]');
var userName = currUser.val() || 'anonymous';
// this is the data we are storing that defines a chat message.
var userMessage = {
text: messageText, // user inputted text
user: userName, // user inputted name
timestamp: Date.now() // current time
};
// use Key#add to insert our message under the chatMessagesKey. This will
// automatically generate a unique subkey name and store our userMessage
// object as the generated key's value.
//
// It is worth noting that the uniquely generated subkey names are also
// guaranteed to be ordered such that each subsequent name is semantically
// larger than the previously generated name. This makes having a timestamp
// in the userMessage somewhat redundant and even prone to error if the
// computer time of user sending the new message is not accurate.
chatMessagesKey.add(userMessage);
// clear out the added text message but not the existing user name.
newMessage.val('');
}
});
// Handle clicks on the delete buttons associated with each chat message.
$('#messages').on('click', 'li button', function(e) {
// get the id of the message to be removed.
var removeId = $(e.currentTarget).parent()[0].id;
// create the Key representing this message and remove that key. We
// will be notified of the removal via a Query event.
var removeMessageKey = chatMessagesKey.key(removeId);
removeMessageKey.remove();
});
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment