Skip to content

Instantly share code, notes, and snippets.

@mianuddin
Last active November 15, 2021 20:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mianuddin/e58271d3dcbd281dc88d58dd7b76da06 to your computer and use it in GitHub Desktop.
Save mianuddin/e58271d3dcbd281dc88d58dd7b76da06 to your computer and use it in GitHub Desktop.
Sample Messaging Web App (with Bitmoji Kit)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Sample Chat</title>
<!-- CSS -->
<link href="https://fonts.googleapis.com/css?family=Oswald:700|Material+Icons" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="app">
<div id="messages"></div>
<div class="controls">
<input id="messageInput" type="text" placeholder="Type a message..."/>
<i id="namePicker" class="material-icons">account_box</i>
<div class="bitmojiStickerPicker"></div>
</div>
</div>
<!-- JS -->
<script src="https://www.gstatic.com/firebasejs/5.7.0/firebase.js"></script>
<script src="script.js"></script>
<script>
// Load the SDK asynchronously
(function (d, s, id) {
var js, sjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "https://sdk.snapkit.com/js/v1/login_bitmoji.js";
sjs.parentNode.insertBefore(js, sjs);
}(document, 'script', 'bitmojikit-sdk'));
</script>
</body>
</html>
/* Initialize Firebase */
firebase.initializeApp({
/* Fill in the following values based on your config. */
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: ""
});
firebase.firestore().settings({
timestampsInSnapshots: true
});
/* Define firebase refs */
const messagesRef = firebase.firestore().collection("messages");
/* Define DOM elements */
const messageInputDOM = document.getElementById("messageInput");
const namePickerDOM= document.getElementById("namePicker");
const messagesDOM = document.getElementById("messages");
/* Define global variables */
const sessionId = btoa(Math.random()).substring(0, 16);
let userName;
/* Define helper functions */
const scrollToBottom = (element) => {
if (element) element.scrollTop = element.scrollHeight;
};
const createParagraph = (content) => {
const newParagraph = document.createElement("p");
if (content) {
const contentEl = document.createTextNode(content);
newParagraph.appendChild(contentEl);
}
return newParagraph;
};
const sendMessage = (message) => {
messagesRef.add({
message,
time: firebase.firestore.Timestamp.now(),
session: sessionId,
name: userName || "Anonymous",
});
};
const sendImage = (image) => {
messagesRef.add({
image,
time: firebase.firestore.Timestamp.now(),
session: sessionId,
name: userName || "Anonymous",
});
};
/* Setup message listener */
messagesRef.orderBy("time").onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
const { session, name, image, message, time } = change.doc.data();
const messageEl = document.createElement("div");
messageEl.className = `message${session === sessionId ? " own" : ""}`;
const nameEl = createParagraph(name);
nameEl.className = "name";
messageEl.appendChild(nameEl);
const messageContentEl = document.createElement("div");
messageContentEl.className = "messageContent";
if (change.doc.data().image !== undefined) {
const imageEl = document.createElement("img");
imageEl.className = "image";
imageEl.setAttribute("src", image);
imageEl.setAttribute("height", "256px");
messageContentEl.appendChild(imageEl);
}
if (change.doc.data().message !== undefined) {
const msgTextEl = createParagraph(message);
messageContentEl.appendChild(msgTextEl);
}
messageEl.appendChild(messageContentEl);
var timestampEl = createParagraph(time.toDate());
timestampEl.className = "timestamp";
messageEl.appendChild(timestampEl);
messagesDOM.appendChild(messageEl);
}
});
scrollToBottom(messagesDOM);
});
/* Setup event listeners */
namePickerDOM.addEventListener("click", () => {
userName = prompt("What's your name?").substring(0, 16);
namePickerDOM.parentNode.removeChild(namePickerDOM);
});
messageInputDOM.addEventListener("keydown", (event) => {
if (event.which === 13 || event.keyCode === 13) {
sendMessage(messageInputDOM.value);
messageInputDOM.value = "";
}
});
/* Setup Bitmoji Kit Web here */
window.snapKitInit = () => {
const bitmojiWebPickerIconClass = "bitmojiStickerPicker";
const uiOptions = {
onStickerPickCallback: sendImage,
webpickerPosition: "topLeft",
};
const loginParamsObj = {
clientId: /* your client id here */,
redirectURI: "http://localhost:8081/",
scopeList: [
"user.bitmoji.avatar",
"user.display_name",
]
};
snap.bitmojikit.mountBitmojiStickerPickerIcons(
bitmojiWebPickerIconClass,
uiOptions,
loginParamsObj
);
}
body {
background: #ffffff;
font-family: sans-serif;
margin: 0;
padding: 0;
}
.app {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
margin: 0 auto;
overflow-x: hidden;
}
@media (min-width: 991.98px) {
.app {
width: 64vw;
border-left: 1px solid #e5e5e5;
border-right: 1px solid #e5e5e5;
}
}
#messages {
height: 80vh;
overflow-y: scroll;
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
flex: 1;
}
.name {
color: #a7a7a7;
font-size: 1rem;
margin-bottom: 0.5em;
}
.timestamp {
color: #c7c7c7;
font-size: 0.75em;
}
.message {
margin: 1em;
display: inline-block;
}
.own {
align-self: flex-end;
}
.messageContent {
padding: 1em;
border-radius: 1em;
background: #F0F0F0;
}
.own .messageContent {
background: #098CFE;
color: white;
}
.controls {
display: flex;
width: 100%;
justify-content: flex-end;
border-top: 1px solid #e5e5e5;
}
#messageInput {
flex: 1;
border: none;
font-size: 1em;
padding: 1em;
}
#namePicker {
color: #098CFE;
font-size: 48px;
display: flex;
align-items: center;
cursor: pointer;
margin: 0 0.5rem;
}
.bitmojiStickerPicker {
margin: 0.5rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment