diff --git a/app.js b/app.js index 3eca10f..ba91aeb 100644 --- a/app.js +++ b/app.js @@ -55,7 +55,7 @@ let kara = new Vue({ this.askForName(); } - this.isTyping = false; + this.stopTyping(); } else { this.welcomeBack(); } @@ -74,7 +74,8 @@ let kara = new Vue({ "Hi! I'm " + this.name + ". :)", "Hi, nice to meet you! My name is " + this.name + ". :)" ] - ) + ), + false ); }, welcomeBack() { @@ -85,7 +86,8 @@ let kara = new Vue({ "Welcome back! :)", "Hey :) Good to see you :)", ] - ) + ), + false ); }, @@ -97,7 +99,8 @@ let kara = new Vue({ 'Whats your name? :)', 'How can i call you?', 'How did your developers call you? :)' - ]) + ]), + false ); this.askedForName = true; @@ -114,8 +117,6 @@ let kara = new Vue({ "Nice to meet you, " + this.username + ". :D" ]) ) - - this.updateStorage(); }, // Messages / Chat @@ -142,14 +143,21 @@ let kara = new Vue({ this.scrollDown(); }, 1000); + this.stopTyping(); this.updateStorage(); }, - botMessage(message) { + botMessage(message, save = true) { this.addMessage(message, true); if (this.talk) { this.say(message); } + + this.stopTyping(); + + if (save) { + this.updateStorage(); + } }, userMessage(body) { this.addMessage(body, false); @@ -174,13 +182,11 @@ let kara = new Vue({ this.react(message, true); }, react(message, recursive = false) { - this.isTyping = true; + this.startTyping(); if (message.search('/') === 0 && !recursive) { setTimeout(() => { this.processCommands(message); - - this.isTyping = false; this.scrollDown(); }, 1000); } else { @@ -199,7 +205,6 @@ let kara = new Vue({ this.updateStorage(); } - this.isTyping = false; this.scrollDown(); }, 1800); } @@ -315,7 +320,7 @@ let kara = new Vue({ } if (this.includesAllOf(keywords, ['weather']) && - this.includesOneOf(keywords, ['how', 'whats']) + this.includesOneOf(keywords, ['how','hows', 'what', 'whats']) ) { this.checkWeather(); return false; @@ -331,22 +336,18 @@ let kara = new Vue({ return false; } - if (this.includesAllOf(keywords, ['cat']) && - this.includesOneOf(keywords, ['images', 'photos', 'send']) - ) { - this.getRandomCat(); + if (this.includesAllOf(keywords, ['birb', 'meme'])) { + this.getRandomMeme('birbmemes'); return false; } - if (this.includesOneOf(keywords, ['doggo', 'dog', 'shiba']) && - this.includesOneOf(keywords, ['images', 'photos', 'send']) - ) { - this.getRandomShiba(); + if (this.includesAllOf(keywords, ['anime', 'meme'])) { + this.getRandomMeme('animememes'); return false; } - if (this.includesAllOf(keywords, ['dank', 'meme'])) { - this.getRandomMeme('dankmemes') + if (this.includesAllOf(keywords, ['coding', 'meme'])) { + this.getRandomMeme('codingmemes'); return false; } @@ -403,7 +404,7 @@ let kara = new Vue({ return answer; } - this.botMessage("I don't know what to say.."); + this.rsaBackupAnswer(message); }, // Forms @@ -413,7 +414,6 @@ let kara = new Vue({ this.location = this.settingsModal.location; this.updateStorage(); - // this.botMessage('Settings saved! :)'); this.scrollDown(); }, @@ -506,7 +506,7 @@ let kara = new Vue({ if (commandFound) { return; } - let commandString = '/' + command; + let commandString = '/' + command.toLowerCase(); if (message.search(commandString) === 0) { parameter = message.replace(commandString, '').trim(); @@ -517,10 +517,10 @@ let kara = new Vue({ return parameter ? parameter : commandFound; }, checkWeather() { - let vue = this; + let Kara = this; - if (!vue.location) { - vue.botMessage('Please set your location in the settings. ⚙'); + if (!Kara.location) { + Kara.botMessage('Please set your location in the settings. ⚙'); return; } @@ -529,17 +529,17 @@ let kara = new Vue({ axios.get(url) .then(function (response) { - vue.botMessage('In ' + response.data.name + ' it\'s ' + response.data.main.temp.toFixed() + '°C with ' + response.data.weather[0].description + '.'); + Kara.botMessage('In ' + response.data.name + ' it\'s ' + response.data.main.temp.toFixed() + '°C with ' + response.data.weather[0].description + '.'); }) .catch(function (error) { alertify.notify(error, 'danger'); - vue.botMessage('I couldn\'t check the weather for your location. 🤔'); + Kara.botMessage('I couldn\'t check the weather for your location. 🤔'); }) this.updateStorage(); }, getRandomMeme(category = 'memes') { - let vue = this; + let Kara = this; let url = 'https://meme-api.herokuapp.com/gimme/'; let categorySet = false; @@ -553,24 +553,24 @@ let kara = new Vue({ axios.get(url + category) .then(function (response) { - vue.addImageMessage({ + Kara.addImageMessage({ body: response.data.title, src: response.data.url }, true); - vue.lastMessageData = { + Kara.lastMessageData = { meme: true, category: category }; }) .catch(function (error) { - vue.botMessage("Hmm.. i can't think of any good memes right now, sorry.. 😞"); + Kara.botMessage("Hmm.. i can't think of any good memes right now, sorry.. 😞"); }) this.updateStorage(); }, tellJoke(category) { - let vue = this; + let Kara = this; let categorySet = false; if (category !== true && category !== false) { @@ -586,14 +586,14 @@ let kara = new Vue({ .then(function (response) { let joke = response.data[0]; - vue.botMessage(joke.setup); + Kara.botMessage(joke.setup); setTimeout(() => { - vue.botMessage(joke.punchline); - vue.scrollDown(); + Kara.botMessage(joke.punchline); + Kara.scrollDown(); }, 3500); - vue.lastMessageData = { + Kara.lastMessageData = { joke: true, category: category }; @@ -602,54 +602,54 @@ let kara = new Vue({ console.log(error); if (categorySet) { - vue.botMessage("Sorry, i don't know any jokes about this topic.. 🙄"); + Kara.botMessage("Sorry, i don't know any jokes about this topic.. 🙄"); } else { - vue.botMessage("I can't remember any jokes right now, sorry. 😢"); + Kara.botMessage("I can't remember any jokes right now, sorry. 😢"); } }); this.updateStorage(); }, startQuiz() { - let vue = this; + let Kara = this; let url = 'https://jservice.io/api/random'; axios.get(url) .then(function (response) { let clue = response.data[0]; - vue.botMessage('Okay! Here is your question from the category "' + clue.category.title + '":'); - vue.botMessage(clue.question); + Kara.botMessage('Okay! Here is your question from the category "' + clue.category.title + '":'); + Kara.botMessage(clue.question); - vue.lastMessageData = { + Kara.lastMessageData = { isTrivia: true, answer: clue.answer }; }) .catch(function (error) { - vue.botMessage("It's not a good time for a quiz."); + Kara.botMessage("It's not a good time for a quiz."); }); this.updateStorage(); }, startJeopardy() { - let vue = this; + let Kara = this; let url = 'https://jservice.io/api/random'; axios.get(url) .then(function (response) { let clue = response.data[0]; - vue.botMessage('Okay! Here we go. The category is "' + clue.category.title + '":'); - vue.botMessage(clue.answer); + Kara.botMessage('Okay! Here we go. The category is "' + clue.category.title + '":'); + Kara.botMessage(clue.answer); - vue.lastMessageData = { + Kara.lastMessageData = { isJeopardy: true, question: clue.question }; }) .catch(function (error) { - vue.botMessage("It's not a good time for a quiz."); + Kara.botMessage("It's not a good time for a quiz."); }); this.updateStorage(); @@ -704,54 +704,75 @@ let kara = new Vue({ // Some Random API Commands rsaRandomAnimalImage(animal, emoji = '😄') { - let vue = this; + let Kara = this; + + Kara.startTyping(); axios.post('/api/curlJson', { url: 'https://some-random-api.ml/img/' + animal }) .catch((error) => { - vue.botMessage("Sorry, i can't find any good pictures right now 🙁" + emoji); + Kara.botMessage("Sorry, i can't find any good pictures right now 🙁" + emoji); }) .then((response) => { - vue.addImageMessage({ + Kara.addImageMessage({ body: emoji, src: response.data.link }, true); }) }, rsaRandomAnimalFact(animal, emoji = '😄') { - let vue = this; + let Kara = this; + + Kara.startTyping(); axios.post('/api/curlJson', { url: 'https://some-random-api.ml/facts/' + animal }) .catch((error) => { - vue.botMessage("Sorry, i can't think of any good facts right now 🙁" + emoji); + Kara.botMessage("Sorry, i can't think of any good facts right now 🙁" + emoji); }) .then((response) => { - vue.botMessage(response.data.fact); + Kara.botMessage(response.data.fact); }) }, rsaLyrics(searchFor) { - let vue = this; + let Kara = this; + + Kara.startTyping(); axios.post('/api/curlJson', { url: 'https://some-random-api.ml/lyrics/?title=' + searchFor.replace(' ', '%20') }) .catch((error) => { - vue.botMessage("Hmm.. i just can't remember the lyrics, but i love that song! 🎵🎧"); + Kara.botMessage("Hmm.. i just can't remember the lyrics, but i love that song! 🎵🎧"); }) .then((response) => { - vue.addImageMessage({ + Kara.addImageMessage({ body: "Here you go!
" + "
" + response.data.title + ' from ' + response.data.author + '
' + '
' + response.data.lyrics, src: response.data.thumbnail.genius - }); + }, true); }) }, + rsaBackupAnswer(message) { + let Kara = this; + + Kara.startTyping(); + + axios.post('/api/curlJson', { + url: 'https://some-random-api.ml/chatbot?message=' + message + }) + .catch((error) => { + Kara.botMessage("I don't know what to say.."); + }) + .then((response) => { + Kara.botMessage(response.data.response); + }); + }, // LocalStorage getSavedData() { @@ -800,6 +821,13 @@ let kara = new Vue({ scrollTop: ($('#chat-box')[0].scrollHeight * 10) }, 800); }, + startTyping() { + this.isTyping = true; + }, + stopTyping() { + this.scrollDown(); + this.isTyping = false; + }, oneOf(answers) { let amountOfAnswers = answers.length; let randomIndex = Math.floor(Math.random() * (amountOfAnswers)); @@ -876,22 +904,22 @@ let kara = new Vue({ // Ajax calls for saving/receiving reactions & themes getBootswatchThemes() { - let vue = this; + let Kara = this; axios.get('https://bootswatch.com/api/4.json') .then(function (response) { - vue.themes = response.data.themes; + Kara.themes = response.data.themes; }) .catch(function (error) { console.log(error); }) }, getReactions() { - let vue = this; + let Kara = this; axios.get('/reactions/get').then((response) => { response.data.forEach((reaction) => { - vue.reactions.push(JSON.parse(reaction.reaction)); + Kara.reactions.push(JSON.parse(reaction.reaction)); }); }).catch((error) => { console.log(error); diff --git a/documentation.md b/documentation.md new file mode 100644 index 0000000..a563cde --- /dev/null +++ b/documentation.md @@ -0,0 +1,74 @@ +#### Commands + + +##### ```/clear``` +Clears the chat. + +##### ```/say``` +Repeats your message. + +##### ```/todo``` +Adds a new todo to the list.\ +Todos can be viewed by clicking on the clipboard-icon in the upper right. + +##### ```/weather``` +Tells you the weather in your location.\ +Your location can be set in the settings.\ +\ +Can be triggered by messages like: +- _How is the weather?_ + +##### ```/joke``` +Tells a joke with an opener and a delayed punchline.\ +Categories are: general (default), knock-knock, programming +\ +Can be triggered by messages like: +- _Tell me a joke_ +- _Tell me a knock knock joke_ +- _Tell me a programming joke_ + +##### ```/meme``` +Sends a random meme from reddit.\ +You can pass a subreddit of your choice (Yes, NSFW too..) +\ +Some predefined meme-categories can be triggerd by: +- _Send me a coding meme_ +- _Send me a dank meme_ +- _Send me a birb meme_ + + +##### ```/me``` +Sends a classical "_User farted_" message. + +##### Animal images & facts +There are a number of commands to receive random animal images & facts.\ + +Animals:\ +_birb, dog, cat, fox, panda, red_panda & koala_ + +To get a fact or an image, use: +```/youranimalImg``` or ```/youranimalFact``` + + +##### ```/lyrics``` +Fetch lyrics for songs.\ +Usage: ```/lyrics songname``` (you can also search for things like ```songname artist```) + +##### ```/quiz``` +Get a quiz-question and guess the answer.\ +You can always give up by typing "i give up". + +##### ```/jeopardy``` +The opposite of ```/quiz```.\ +Guess the right question to the given answer. + +##### ```/dice``` +Roll the dice! + +--- + +#### Experimental + +##### ```/talk``` +Activate talking. Kara will now talk to you.\ +The voice-language heavily depends on the device used. \ No newline at end of file diff --git a/index.html b/index.html index f06d0e7..5f5a92e 100644 --- a/index.html +++ b/index.html @@ -22,6 +22,9 @@
+
+ +
@@ -157,6 +160,34 @@ + + +