diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fa5818d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# Ignore tunneling tool
+/ngrok
diff --git a/component/Bubbles.js b/component/Bubbles.js
index be231e7..7b3a2e6 100644
--- a/component/Bubbles.js
+++ b/component/Bubbles.js
@@ -1,18 +1,52 @@
function Bubbles(container, self, options) {
// options
- options = typeof options !== "undefined" ? options : {};
+ options = typeof options !== "undefined" ? options : {};
animationTime = options.animationTime || 200; // how long it takes to animate chat bubble, also set in CSS
typeSpeed = options.typeSpeed || 5; // delay per character, to simulate the machine "typing"
widerBy = options.widerBy || 2; // add a little extra width to bubbles to make sure they don't break
sidePadding = options.sidePadding || 6; // padding on both sides of chat bubbles
+ inputCallbackFn = options.inputCallbackFn || (function(o){ return false }); // should we display an input field?
+ var standingAnswer = "ice"; // remember where to restart convo if interrupted
+
+
+
// set up the stage
container.classList.add("bubble-container");
var bubbleWrap = document.createElement("div");
bubbleWrap.className = "bubble-wrap";
container.appendChild(bubbleWrap);
+ // install user input textfield
+ this.typeInput = function(callbackFn){
+ var inputWrap = document.createElement("div");
+ inputWrap.className = "input-wrap";
+ var inputText = document.createElement("textarea");
+ inputText.setAttribute("placeholder", "Type your question...");
+ inputWrap.appendChild(inputText);
+ inputText.addEventListener("keypress", function(e){ // register user input
+ if(e.keyCode == 13){
+ e.preventDefault();
+ typeof bubbleQueue !== false ? clearTimeout(bubbleQueue) : false; // allow user to interrupt the bot
+ var lastBubble = document.querySelectorAll(".bubble.say"); lastBubble = lastBubble[lastBubble.length-1];
+ lastBubble.classList.contains("reply") && !lastBubble.classList.contains("reply-freeform") ? lastBubble.classList.add("bubble-hidden") : false;
+ addBubble("" + this.value + "", function(){}, "reply reply-freeform");
+ // callback
+ typeof callbackFn === "function" ? callbackFn({
+ "input" : this.value,
+ "convo" : convo,
+ "standingAnswer": standingAnswer
+ }) : false;
+ this.value = "";
+ }
+ });
+ container.appendChild(inputWrap);
+ bubbleWrap.style.paddingBottom = "100px";
+ }
+ inputCallbackFn ? this.typeInput(inputCallbackFn) : false;
+
+
// init typing bubble
var bubbleTyping = document.createElement("div");
@@ -25,9 +59,10 @@ function Bubbles(container, self, options) {
bubbleWrap.appendChild(bubbleTyping);
// accept JSON & create bubbles
- this.talk = function(convo) {
+ this.talk = function(convo, here) {
this.convo = convo;
- this.reply();
+ this.reply(this.convo[here]);
+ here ? standingAnswer = here : false;
}
this.reply = function(turn) {
turn = typeof turn !== "undefined" ? turn : this.convo.ice;
@@ -52,7 +87,7 @@ function Bubbles(container, self, options) {
// navigate "answers"
this.answer = function(key){
var func = function(key){ typeof window[key] === "function" ? window[key]() : false; }
- this.convo[key] !== undefined ? this.reply(this.convo[key]) : func(key);
+ this.convo[key] !== undefined ? (this.reply(this.convo[key]), standingAnswer = key) : func(key);
};
// api for typing bubble
@@ -77,7 +112,10 @@ function Bubbles(container, self, options) {
start();
}
+
+
// create a bubble
+ var bubbleQueue = false;
var addBubble = function(say, posted, reply){
reply = typeof reply !== "undefined" ? reply : "";
// create bubble element
@@ -91,7 +129,10 @@ function Bubbles(container, self, options) {
// answer picker styles
if(reply !== ""){
var bubbleButtons = bubbleContent.querySelectorAll(".bubble-button");
- bubbleButtons.forEach(function(el){ el.style.width = el.offsetWidth - sidePadding * 2 + widerBy + "px"; });
+ bubbleButtons.forEach(function(el){
+ if(!el.parentNode.parentNode.classList.contains("reply-freeform"))
+ el.style.width = el.offsetWidth - sidePadding * 2 + widerBy + "px";
+ });
bubble.addEventListener("click", function(){
bubbleButtons.forEach(function(el){
el.style.width = 0 + "px";
@@ -110,7 +151,7 @@ function Bubbles(container, self, options) {
setTimeout(function() { bubbleTyping.classList.remove("imagine"); }, animationTime );
}
setTimeout(function() { bubbleTyping.classList.add("imagine"); }, wait - animationTime * 2 );
- setTimeout(function() {
+ bubbleQueue = setTimeout(function() {
bubble.classList.remove("imagine");
var bubbleWidthCalc = bubbleContent.offsetWidth + widerBy + "px";
bubble.style.width = reply == "" ? bubbleWidthCalc : "";
@@ -134,4 +175,6 @@ function Bubbles(container, self, options) {
}, wait + animationTime * 2);
}
-}
\ No newline at end of file
+
+
+} // close function
\ No newline at end of file
diff --git a/component/start-here/hello.html b/component/start-here/hello.html
index 55865c2..a96ccfa 100644
--- a/component/start-here/hello.html
+++ b/component/start-here/hello.html
@@ -12,6 +12,7 @@
+
@@ -322,7 +323,43 @@