diff --git a/app.css b/app.css index edf3cfc..2c27e5a 100644 --- a/app.css +++ b/app.css @@ -62,4 +62,12 @@ body { .form-button { width: 100%; +} + +.command-message { + color: grey; +} + +.command-message::before { + content: '$: '; } \ No newline at end of file diff --git a/app.js b/app.js index 4599636..3adefda 100644 --- a/app.js +++ b/app.js @@ -1,8 +1,15 @@ let kara = new Vue({ el: '#kara', data: { + features: { + changeName: false, + themes: true, + ownReactions: false, + setNameAtStart: true + }, messages: [], lastMessage: null, + lastMessageData: {}, name: 'Kara', location: null, chatbox: null, @@ -52,7 +59,9 @@ let kara = new Vue({ }, mounted() { this.getSavedData(); - this.getBootswatchThemes(); + if (this.features.themes) { + this.getBootswatchThemes(); + } this.settingsModal = { name: this.name, @@ -62,7 +71,10 @@ let kara = new Vue({ if (!this.username || this.username === "null") { this.initialGreeting(); - this.askForName(); + + if (this.features.setNameAtStart) { + this.askForName(); + } this.isTyping = false; } else { @@ -79,6 +91,7 @@ let kara = new Vue({ this.messages.push({ body: body, bot: bot, + command: body.search('/') === 0, time: Date.now() }) }, @@ -127,31 +140,73 @@ let kara = new Vue({ react(message) { this.isTyping = true; - setTimeout(() => { - // Check commands - if (this.checkForCommands(message, 'note')) { - let noteToSave = this.checkForCommands(message, 'note'); - this.saveNote(noteToSave); - } else if (this.checkForCommands(message, 'clear')) { - this.clearChat(); - } else if (this.checkForCommands(message, 'weather')) { - this.checkWeather(); - } else if (this.askedForName === true) { - this.setName(message) - } else if (this.takeNote === true) { - this.saveNote(message) - } else { - let answer = this.getAnswer(message); - if (answer) { - this.botMessage(answer); + if (message.search('/') === 0) { + setTimeout(() => { + this.processCommands(message); + + this.isTyping = false; + this.scrollDown(); + }, 1000); + } else { + setTimeout(() => { + // Check commands + if (this.askedForName === true) { + this.setName(message); + } else if (this.takeNote === true) { + this.saveNote(message); + } else { + let answer = this.getAnswer(message); + if (answer) { + this.botMessage(answer); + } + + this.updateStorage(); } - this.updateStorage(); + this.isTyping = false; + this.scrollDown(); + }, 1800); + } + }, + processCommands(message) { + if (this.checkForCommands(message, 'note')) { + let noteToSave = this.checkForCommands(message, 'note'); + this.saveNote(noteToSave); + } + + if (this.checkForCommands(message, 'clear')) { + this.clearChat(); + } + + if (this.checkForCommands(message, 'weather')) { + this.checkWeather() + } + + if (this.checkForCommands(message, 'joke')) { + this.tellJoke(this.checkForCommands(message, 'joke')) + } + }, + checkForCommands(message, commands) { + if (!Array.isArray(commands)) { + commands = [commands]; + } + + let commandFound = false; + let parameter = false; + + commands.forEach((command) => { + if (commandFound) { + return; } + let commandString = '/' + command; - this.isTyping = false; - this.scrollDown(); - }, 2000); + if (message.search(commandString) === 0) { + parameter = message.replace(commandString, '').trim(); + commandFound = true; + } + }); + + return parameter ? parameter : commandFound; }, scrollDown() { $('#chat-box').stop().animate({ @@ -192,28 +247,6 @@ let kara = new Vue({ return includesAllPhrases; }, - checkForCommands(message, commands) { - if (!Array.isArray(commands)) { - commands = [commands]; - } - - let commandFound = false; - let parameter = false; - - commands.forEach((command) => { - if (commandFound) { - return; - } - let commandString = '/' + command; - - if (message.search(commandString) === 0) { - parameter = message.replace(commandString, '').trim(); - commandFound = true; - } - }); - - return parameter ? parameter : commandFound; - }, cleanupMessage(message) { message = message.toLowerCase(); return message.replace('?', '') @@ -246,13 +279,17 @@ let kara = new Vue({ let phrases = message.split(' '); let answer = undefined; + if (this.lastMessageData.joke && this.includesOneOf(phrases, ['another', 'more'])) { + this.tellJoke(this.lastMessageData.category); + return false; + } + if (this.includesAllOf(phrases, ['change', 'my', 'name'])) { this.askedForName = true; return "Please tell me how i should call you."; } - if ( - this.includesAllOf(phrases, ['new', 'note']) || + if (this.includesAllOf(phrases, ['new', 'note']) || this.includesAllOf(phrases, ['new', 'task']) || this.includesAllOf(phrases, ['save', 'to', 'clipboard']) ) { @@ -269,37 +306,43 @@ let kara = new Vue({ return false; } - if ( - this.includesAllOf(phrases, ['whats', 'the', 'time']) || - this.includesAllOf(phrases, ['how', 'late']) + if (this.includesAllOf(phrases, ['knock', 'joke'])) { + this.tellJoke('knock-knock'); + return false; + } + + if (this.includesAllOf(phrases, ['joke']) && this.includesOneOf(phrases, ['coding', 'programming', 'code', 'it'])) { + this.tellJoke('programming'); + return false; + } + + if (this.includesAllOf(phrases, ['tell', 'joke']) || + this.includesAllOf(phrases, ['something', 'funny']) || + this.includesAllOf(phrases, ['cheer', 'me', 'up']) ) { + this.tellJoke('general'); + return false; + } + + if (this.includesAllOf(phrases, ['whats', 'the', 'time']) || this.includesAllOf(phrases, ['how', 'late'])) { return "It's " + moment().format('LT'); } - if ( - this.includesAllOf(phrases, ['what', 'day', 'it']) - ) { + if (this.includesAllOf(phrases, ['what', 'day', 'it'])) { return "It's " + moment().format('dddd') + "."; } - if ( - this.includesAllOf(phrases, ['what', 'date', 'it']) || - this.includesAllOf(phrases, ['whats', 'the', 'date']) - ) { + if (this.includesAllOf(phrases, ['what', 'date', 'it']) || this.includesAllOf(phrases, ['whats', 'the', 'date'])) { return "It's " + moment().format('dddd') + ", " + moment().format('MMMM Do YYYY') + "."; } this.answers.forEach((answerOption) => { if (answerOption.includeAll === true) { - if ( - this.includesAllOf(phrases, answerOption.keywords) - ) { + if (this.includesAllOf(phrases, answerOption.keywords)) { answer = this.oneOf(answerOption.responses); } } else { - if ( - this.includesOneOf(phrases, answerOption.keywords) - ) { + if (this.includesOneOf(phrases, answerOption.keywords)) { answer = this.oneOf(answerOption.responses); } } @@ -435,14 +478,22 @@ let kara = new Vue({ }, clearChat() { this.messages = []; - this.botMessage('Chat cleared.'); + this.botMessage(this.oneOf([ + 'Chat cleared.', + 'Evidence destroyed.', + 'Mind cleared.', + 'Uhm.. i think forgot everything we ever talked about.. oops.', + 'A fresh start!', + "You've got something to hide? Nevermind, gotcha fam. Chat is cleared now. 🐱👤" + ])); + this.updateStorage(); }, checkWeather() { let vue = this; if (!vue.location) { - vue.botMessage('Please set your location in the settings.'); + vue.botMessage('Please set your location in the settings. ⚙'); return; } @@ -455,8 +506,50 @@ let kara = new Vue({ }) .catch(function (error) { console.log(error); - vue.botMessage('I couldn\'t check the weather for your location.'); + vue.botMessage('I couldn\'t check the weather for your location. 🤔'); + }) + + this.updateStorage(); + }, + tellJoke(category) { + let vue = this; + let categorySet = false; + + if (category !== true && category !== false) { + category = category.trim(); + categorySet = true; + } else { + category = 'general' + } + + let url = 'https://official-joke-api.appspot.com/jokes/' + category + '/random'; + + axios.get(url) + .then(function (response) { + console.log(response); + let joke = response.data[0]; + + vue.botMessage(joke.setup); + + setTimeout(() => { + vue.botMessage(joke.punchline); + vue.scrollDown(); + }, 3500); + + vue.lastMessageData = { + joke: true, + category: category + }; }) + .catch(function (error) { + console.log(error); + + if (categorySet) { + vue.botMessage("Sorry, i don't know any jokes about this topic.. 🙄"); + } else { + vue.botMessage("I can't remember any jokes right now, sorry. 😢"); + } + }); this.updateStorage(); }, diff --git a/img/luna.png b/img/luna.png new file mode 100644 index 0000000..241a332 Binary files /dev/null and b/img/luna.png differ diff --git a/index.html b/index.html index 176c8df..7325b23 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ Kara + @@ -15,7 +16,7 @@