diff --git a/app.css b/app.css index 25465bb..3d5e419 100644 --- a/app.css +++ b/app.css @@ -1,112 +1,108 @@ -body { - margin: 15px; - padding: 0; -} - -#kara { - margin: 0; - padding: 0; - width: auto; -} - -@media (min-width: 40em) { - #kara, - #kara-banner, - #chatbox-wrapper { - margin-left: auto; - margin-right: auto; - padding: 0; - width: 40em; - } -} - -.message { - color: black; - padding: 10px; - margin-bottom: 5px; - min-width: 55%; - max-width: 80%; -} - -img.message-image { - max-width: 60%; - border-radius: 0 15px 15px 15px; - - margin-bottom: 5px; - clear: top; -} - -.bot-message { - border-radius: 0 15px 15px 15px; - background-color: lightgreen; -} - -.user-message { - border-radius: 15px 0 15px 15px; - background-color: lightblue; -} - -#chat-box { - margin-top: 4em; - overflow-y: scroll; - height: 65vh; - padding-bottom: 2em; -} - -#chatbox-wrapper { - position: fixed; - padding: 1em; - bottom: 0; - left: 0; - right: 0; -} - -#kara-banner { - position: fixed; - height: 3.2em; - top: 0; - left: 0; - right: 0; - text-align: center; - padding: 0.7em; -} - -#kara-banner .btn, .add-response-input-button { - margin-top: -0.3em; -} - -.response-input { - margin-bottom: 3px; -} - -.form-button { - width: 100%; -} - -.command-message { - color: grey; -} - -.command-message::before { - content: '$: '; -} - -.header-logo { - max-height: 32px; - max-width: 32px; - width: 32px; - height: 32px; - margin-right: 5px; -} - -.me-message { - background-color: orange; -} - -#addForm { - margin-top: 60px; -} - -.fa-check-circle { - color: green; +body { + margin: 15px; + padding: 0; +} + +#kara { + margin: 0; + padding: 0; + width: auto; +} + +@media (min-width: 40em) { + #kara, + #kara-banner, + #chatbox-wrapper { + margin-left: auto; + margin-right: auto; + padding: 0; + width: 40em; + } +} + +.message { + color: black; + padding: 10px; + margin-bottom: 5px; + min-width: 55%; + max-width: 80%; +} + +img.message-image { + max-width: 60%; + border-radius: 0 15px 15px 15px; + + margin-bottom: 5px; + clear: top; +} + +.bot-message { + border-radius: 0 15px 15px 15px; + background-color: lightgreen; +} + +.user-message { + border-radius: 15px 0 15px 15px; + background-color: lightblue; +} + +#chat-box { + margin-top: 4em; + overflow-y: scroll; + height: 65vh; + padding-bottom: 2em; +} + +#chatbox-wrapper { + position: fixed; + padding: 1em; + bottom: 0; + left: 0; + right: 0; +} + +#kara-banner { + position: fixed; + height: 3.2em; + top: 0; + left: 0; + right: 0; + text-align: center; + padding: 0.7em; +} + +#kara-banner .btn, .add-response-input-button { + margin-top: -0.3em; +} + +.response-input { + margin-bottom: 3px; +} + +.form-button { + width: 100%; +} + +.command-message { + color: grey; +} + +.command-message::before { + content: '$: '; +} + +.header-logo { + max-height: 32px; + max-width: 32px; + width: 32px; + height: 32px; + margin-right: 5px; +} + +.me-message { + background-color: orange; +} + +#addForm { + margin-top: 60px; } \ No newline at end of file diff --git a/app.js b/app.js index f810099..15e9299 100644 --- a/app.js +++ b/app.js @@ -1,614 +1,614 @@ -let kara = new Vue({ - el: '#kara', - data: { - features: { - changeName: false, - themes: true, - ownReactions: true, - setNameAtStart: true - }, - messages: [], - lastMessage: null, - lastMessageData: {}, - name: 'Kara', - location: null, - chatbox: null, - isTyping: false, - askedForName: false, - takeTodo: false, - username: '', - themes: null, - activeTheme: 'slate', - talk: false, - addModal: { - includeAll: false, - keywords: '', - responses: [ - 'Answer #1' - ] - }, - settingsModal: { - name: null, - username: null, - location: '' - }, - todos: [], - answers: [ - { - includeAll: false, - keywords: [ - 'hi', 'hallo', 'servas', 'servus', 'hello' - ], - responses: [ - 'Hey! :)', - 'Hello!', - 'How are you?' - ] - }, - { - includeAll: true, - keywords: [ - 'how', 'are', 'you' - ], - responses: [ - 'I\'m good! Thanks for asking! :) How about you?', - 'A bit tired from trying to do that think called "thinking".. i\'ll figure it out one day.', - 'Wooo! I\'m hyped for party! You\'re in?' - ] - } - ] - }, - mounted() { - this.getSavedData(); - if (this.features.themes) { - this.getBootswatchThemes(); - } - - this.settingsModal = { - name: this.name, - username: this.username, - location: this.location - }; - - if (!this.username || this.username === "null") { - this.initialGreeting(); - - if (this.features.setNameAtStart) { - this.askForName(); - } - - this.isTyping = false; - } else { - this.welcomeBack(); - } - - document.getElementById('chatinput').focus(); - document.title = this.name; - - this.scrollDown(); - }, - methods: { - karaTalks(message) { - var speech = new SpeechSynthesisUtterance(); - - // Set the text and voice attributes. - speech.text = message; - speech.volume = 1; - speech.rate = 1; - speech.pitch = 1; - - window.speechSynthesis.speak(speech); - }, - addMessage(body, bot, me = false) { - this.messages.push({ - body: body, - bot: bot, - command: body.search('/') === 0, - me: me, - time: Date.now() - }) - }, - botMessage(body) { - this.addMessage(body, true); - if (this.talk) { - this.karaTalks(body); - } - }, - userMessage(body) { - this.addMessage(body, false); - this.lastMessage = body; - - this.updateStorage(); - }, - initialGreeting() { - this.botMessage( - this.oneOf( - [ - "Hi! I'm " + this.name + ". :)", - "Hi, nice to meet you! My name is " + this.name + ". :)" - ] - ) - ); - - this.updateStorage(); - }, - welcomeBack() { - this.botMessage( - this.oneOf( - [ - "Hi! Haven't heard of you in a while. :)", - "Welcome back! :)", - "Hey :) Good to see you :)", - ] - ) - ); - }, - sendMessage() { - if (this.chatbox.trim() === '') { - return false; - } - - if (this.chatbox.search('/me') !== 0) { - this.userMessage(this.chatbox); - } - this.scrollDown(); - this.react(this.chatbox); - this.chatbox = ''; - }, - react(message, recursive = false) { - this.isTyping = true; - - if (message.search('/') === 0 && !recursive) { - setTimeout(() => { - this.processCommands(message); - - this.isTyping = false; - this.scrollDown(); - }, 1000); - } else { - setTimeout(() => { - // Check commands - if (this.askedForName === true) { - this.setName(message); - } else if (this.takeTodo === true) { - this.saveTodo(message); - } else { - let answer = this.getAnswer(message); - if (answer) { - this.botMessage(answer); - } - - this.updateStorage(); - } - - this.isTyping = false; - this.scrollDown(); - }, 1800); - } - }, - processCommands(message) { - if (this.checkForCommands(message, 'todo')) { - let todoToSave = this.checkForCommands(message, 'todo'); - this.saveTodo(todoToSave); - } - - 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')) - } - - if (this.checkForCommands(message, 'me')) { - this.meMessage(this.checkForCommands(message, 'me')) - } - - if (this.checkForCommands(message, 'say')) { - this.botMessage(this.checkForCommands(message, 'say')) - } - - if (this.checkForCommands(message, 'talk')) { - this.talk = !this.talk; - alertify.notify('Speech ' + this.talk ? 'enabled' : 'disabled'); - } - }, - 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; - }, - scrollDown() { - $('#chat-box').stop().animate({ - scrollTop: ($('#chat-box')[0].scrollHeight * 10) - }, 800); - }, - oneOf(answers) { - let amountOfAnswers = answers.length; - let randomIndex = Math.floor(Math.random() * (amountOfAnswers)); - - return this.convertWildcards(answers[randomIndex]); - }, - convertWildcards(message) { - message = message.replace('$name$', this.username); - message = message.replace('$botname$', this.name); - - return message; - }, - includesOneOf(phrases, wordsToSearch) { - let includes = false; - - wordsToSearch.forEach((searchWord) => { - if (phrases.includes(searchWord)) { - includes = true; - } - }) - - return includes; - }, - includesAllOf(phrases, wordsToSearch) { - let includesAllPhrases = true; - - wordsToSearch.forEach((searchWord) => { - if (!phrases.includes(searchWord)) { - includesAllPhrases = false; - } - }) - - return includesAllPhrases; - }, - cleanupMessage(message) { - message = message.toLowerCase(); - return message.replace('?', '') - .replace('!', '') - .replace('.', '') - .replace(',', '') - .replace('-', '') - .replace('_', '') - .replace('#', '') - .replace('\'', '') - .replace('"', '') - .replace('+', '') - .replace('*', '') - .replace('ยง', '') - .replace('$', '') - .replace('%', '') - .replace('&', '') - .replace('/', '') - .replace('(', '') - .replace(')', '') - .replace('=', '') - .replace('\\', '') - .replace('@', '') - .replace('~', '') - .replace('โฆ', ''); - }, - getAnswer(message) { - message = this.cleanupMessage(message); - - let phrases = message.split(' '); - let answer = undefined; - - if (this.lastMessageData.joke && this.includesOneOf(phrases, ['another', 'more'])) { - this.tellJoke(this.lastMessageData.category); - } - - if (this.includesAllOf(phrases, ['change', 'my', 'name'])) { - this.askedForName = true; - return "Please tell me how i should call you."; - } - - if (this.includesAllOf(phrases, ['new', 'todo']) || - this.includesAllOf(phrases, ['new', 'task']) || - this.includesAllOf(phrases, ['take', 'todo']) || - this.includesAllOf(phrases, ['save', 'to', 'clipboard']) - ) { - this.takeTodo = true; - return this.oneOf([ - "What do you wan't me to save for you?", - "Tell me what you wan't to save.", - "What is it you wan't to save?", - ]); - } - - if (this.includesAllOf(phrases, ['clear', 'chat'])) { - this.clearChat(); - return false; - } - - if (this.includesAllOf(phrases, ['weather']) && - this.includesOneOf(phrases, ['how', 'whats']) - ) { - this.checkWeather(); - return false; - } - - 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'])) { - return "It's " + moment().format('dddd') + "."; - } - - 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)) { - answer = this.oneOf(answerOption.responses); - } - } else { - if (this.includesOneOf(phrases, answerOption.keywords)) { - answer = this.oneOf(answerOption.responses); - } - } - }); - - if (answer) { - return answer; - } - - return 'I don\'t know what to say..'; - }, - addResponseToInput() { - this.addModal.responses.push(''); - }, - addNewResponseContainer() { - let includeAll = this.addModal.includeAll; - let keywords = this.cleanupMessage(this.addModal.keywords).split(','); - let responses = this.addModal.responses; - - this.answers.push({ - includeAll: includeAll, - keywords: keywords, - responses: responses - }); - - this.addModal.includeAll = false; - this.addModal.keywords = ''; - this.addModal.responses = ['']; - - this.updateStorage(); - }, - updateStorage() { - localStorage.setItem('name', this.name); - localStorage.setItem('username', this.username); - localStorage.setItem('activeTheme', this.activeTheme); - localStorage.setItem('messages', JSON.stringify(this.messages)); - localStorage.setItem('answers', JSON.stringify(this.answers)); - localStorage.setItem('todos', JSON.stringify(this.todos)); - localStorage.setItem('lastMessage', JSON.stringify(this.lastMessage)); - localStorage.setItem('location', JSON.stringify(this.location)); - }, - getSavedData() { - let savedName = localStorage.getItem('name'); - - this.name = savedName ? savedName : this.name; - - let savedUsername = localStorage.getItem('username'); - this.username = savedUsername ? savedUsername : null; - - let savedActiveTheme = localStorage.getItem('activeTheme'); - this.activeTheme = savedActiveTheme ? savedActiveTheme : 'slate'; - - let savedMessages = JSON.parse(localStorage.getItem('messages')); - this.messages = savedMessages ? savedMessages : []; - - let savedAnswers = JSON.parse(localStorage.getItem('answers')); - this.answers = savedAnswers ? savedAnswers : []; - - let savedTodos = JSON.parse(localStorage.getItem('todos')); - this.todos = savedTodos ? savedTodos : []; - - let savedLastMessage = JSON.parse(localStorage.getItem('lastMessage')); - this.lastMessage = savedLastMessage ? savedLastMessage : null; - - let savedLocation = JSON.parse(localStorage.getItem('location')); - this.location = savedLocation ? savedLocation : null; - - this.scrollDown(); - }, - askForName() { - this.botMessage( - this.oneOf([ - 'May i ask for your name?', - 'Whats your name? :)', - 'How can i call you?', - 'How did your developers call you? :)' - ]) - ); - - this.askedForName = true; - }, - setName(message) { - this.username = message.trim(); - this.settingsModal.username = this.username; - this.askedForName = false; - this.updateStorage(); - - this.botMessage( - this.oneOf([ - "That's a beautiful name!", - "Okay, i'll call you " + this.username + " from now on :)", - "Nice to meet you, " + this.username + ". :D" - ]) - ) - }, - saveTodo(message) { - this.takeTodo = false; - - this.todos.push({ - time: moment(), - body: message, - checked: false - }); - - this.updateStorage(); - - this.botMessage( - this.oneOf([ - "Saved! :)", - "You can read and check your todos in the clipboard-section. :)" - ]) - ) - }, - clearTodos() { - this.todos = []; - - this.botMessage( - this.oneOf([ - "Todos cleared. ๐ฎ" - ]) - ); - - this.updateStorage(); - }, - saveSettings() { - this.name = this.settingsModal.name; - this.username = this.settingsModal.username; - this.location = this.settingsModal.location; - this.updateStorage(); - - // this.botMessage('Settings saved! :)'); - this.scrollDown(); - }, - clearChat() { - this.messages = []; - 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. โ'); - return; - } - - let city = this.location.toLowerCase(); - let url = 'http://api.openweathermap.org/data/2.5/weather?q=' + city + '&appid=8a1aa336da8899c1038bf6bd808d8961&units=metric'; - - 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 + '.'); - }) - .catch(function (error) { - alert(error); - 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(); - }, - meMessage(message) { - this.addMessage(this.username + ' ' + message, false, true); - this.react(message, true); - }, - clearStorage() { - localStorage.clear(); - location.reload(); - }, - getBootswatchThemes() { - let vue = this; - - axios.get('https://bootswatch.com/api/4.json') - .then(function (response) { - vue.themes = response.data.themes; - }) - .catch(function (error) { - console.log(error); - }) - } - } +let kara = new Vue({ + el: '#kara', + data: { + features: { + changeName: false, + themes: true, + ownReactions: true, + setNameAtStart: true + }, + messages: [], + lastMessage: null, + lastMessageData: {}, + name: 'Kara', + location: null, + chatbox: null, + isTyping: false, + askedForName: false, + takeNote: false, + username: '', + themes: null, + activeTheme: 'slate', + talk: false, + addModal: { + includeAll: false, + keywords: '', + responses: [ + 'Answer #1' + ] + }, + settingsModal: { + name: null, + username: null, + location: '' + }, + notes: [], + answers: [ + { + includeAll: false, + keywords: [ + 'hi', 'hallo', 'servas', 'servus', 'hello' + ], + responses: [ + 'Hey! :)', + 'Hello!', + 'How are you?' + ] + }, + { + includeAll: true, + keywords: [ + 'how', 'are', 'you' + ], + responses: [ + 'I\'m good! Thanks for asking! :) How about you?', + 'A bit tired from trying to do that think called "thinking".. i\'ll figure it out one day.', + 'Wooo! I\'m hyped for party! You\'re in?' + ] + } + ] + }, + mounted() { + this.getSavedData(); + if (this.features.themes) { + this.getBootswatchThemes(); + } + + this.settingsModal = { + name: this.name, + username: this.username, + location: this.location + }; + + if (!this.username || this.username === "null") { + this.initialGreeting(); + + if (this.features.setNameAtStart) { + this.askForName(); + } + + this.isTyping = false; + } else { + this.welcomeBack(); + } + + document.getElementById('chatinput').focus(); + document.title = this.name; + + this.scrollDown(); + }, + methods: { + karaTalks(message) { + var speech = new SpeechSynthesisUtterance(); + + // Set the text and voice attributes. + speech.text = message; + speech.volume = 1; + speech.rate = 1; + speech.pitch = 1; + + window.speechSynthesis.speak(speech); + }, + addMessage(body, bot, me = false) { + this.messages.push({ + body: body, + bot: bot, + command: body.search('/') === 0, + me: me, + time: Date.now() + }) + }, + botMessage(body) { + this.addMessage(body, true); + if (this.talk) { + this.karaTalks(body); + } + }, + userMessage(body) { + this.addMessage(body, false); + this.lastMessage = body; + + this.updateStorage(); + }, + initialGreeting() { + this.botMessage( + this.oneOf( + [ + "Hi! I'm " + this.name + ". :)", + "Hi, nice to meet you! My name is " + this.name + ". :)" + ] + ) + ); + + this.updateStorage(); + }, + welcomeBack() { + this.botMessage( + this.oneOf( + [ + "Hi! Haven't heard of you in a while. :)", + "Welcome back! :)", + "Hey :) Good to see you :)", + ] + ) + ); + }, + sendMessage() { + if (this.chatbox.trim() === '') { + return false; + } + + if (this.chatbox.search('/me') !== 0) { + this.userMessage(this.chatbox); + } + this.scrollDown(); + this.react(this.chatbox); + this.chatbox = ''; + }, + react(message, recursive = false) { + this.isTyping = true; + + if (message.search('/') === 0 && !recursive) { + 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.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')) + } + + if (this.checkForCommands(message, 'me')) { + this.meMessage(this.checkForCommands(message, 'me')) + } + + if (this.checkForCommands(message, 'say')) { + this.botMessage(this.checkForCommands(message, 'say')) + } + + if (this.checkForCommands(message, 'talk')) { + this.talk = !this.talk; + alert(this.talk); + } + }, + 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; + }, + scrollDown() { + $('#chat-box').stop().animate({ + scrollTop: ($('#chat-box')[0].scrollHeight * 10) + }, 800); + }, + oneOf(answers) { + let amountOfAnswers = answers.length; + let randomIndex = Math.floor(Math.random() * (amountOfAnswers)); + + return this.convertWildcards(answers[randomIndex]); + }, + convertWildcards(message) { + message = message.replace('$name$', this.username); + message = message.replace('$botname$', this.name); + + return message; + }, + includesOneOf(phrases, wordsToSearch) { + let includes = false; + + wordsToSearch.forEach((searchWord) => { + if (phrases.includes(searchWord)) { + includes = true; + } + }) + + return includes; + }, + includesAllOf(phrases, wordsToSearch) { + let includesAllPhrases = true; + + wordsToSearch.forEach((searchWord) => { + if (!phrases.includes(searchWord)) { + includesAllPhrases = false; + } + }) + + return includesAllPhrases; + }, + cleanupMessage(message) { + message = message.toLowerCase(); + return message.replace('?', '') + .replace('!', '') + .replace('.', '') + .replace(',', '') + .replace('-', '') + .replace('_', '') + .replace('#', '') + .replace('\'', '') + .replace('"', '') + .replace('+', '') + .replace('*', '') + .replace('ยง', '') + .replace('$', '') + .replace('%', '') + .replace('&', '') + .replace('/', '') + .replace('(', '') + .replace(')', '') + .replace('=', '') + .replace('\\', '') + .replace('@', '') + .replace('~', '') + .replace('โฆ', ''); + }, + getAnswer(message) { + message = this.cleanupMessage(message); + + let phrases = message.split(' '); + let answer = undefined; + + if (this.lastMessageData.joke && this.includesOneOf(phrases, ['another', 'more'])) { + this.tellJoke(this.lastMessageData.category); + } + + 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']) || + this.includesAllOf(phrases, ['new', 'task']) || + this.includesAllOf(phrases, ['take', 'note']) || + this.includesAllOf(phrases, ['save', 'to', 'clipboard']) + ) { + this.takeNote = true; + return this.oneOf([ + "What do you wan't me to save for you?", + "Tell me what you wan't to save.", + "What is it you wan't to save?", + ]); + } + + if (this.includesAllOf(phrases, ['clear', 'chat'])) { + this.clearChat(); + return false; + } + + if (this.includesAllOf(phrases, ['weather']) && + this.includesOneOf(phrases, ['how', 'whats']) + ) { + this.checkWeather(); + return false; + } + + 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'])) { + return "It's " + moment().format('dddd') + "."; + } + + 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)) { + answer = this.oneOf(answerOption.responses); + } + } else { + if (this.includesOneOf(phrases, answerOption.keywords)) { + answer = this.oneOf(answerOption.responses); + } + } + }); + + if (answer) { + return answer; + } + + return 'I don\'t know what to say..'; + }, + addResponseToInput() { + this.addModal.responses.push(''); + }, + addNewResponseContainer() { + let includeAll = this.addModal.includeAll; + let keywords = this.cleanupMessage(this.addModal.keywords).split(','); + let responses = this.addModal.responses; + + this.answers.push({ + includeAll: includeAll, + keywords: keywords, + responses: responses + }); + + this.addModal.includeAll = false; + this.addModal.keywords = ''; + this.addModal.responses = ['']; + + this.updateStorage(); + }, + updateStorage() { + localStorage.setItem('name', this.name); + localStorage.setItem('username', this.username); + localStorage.setItem('activeTheme', this.activeTheme); + localStorage.setItem('messages', JSON.stringify(this.messages)); + localStorage.setItem('answers', JSON.stringify(this.answers)); + localStorage.setItem('notes', JSON.stringify(this.notes)); + localStorage.setItem('lastMessage', JSON.stringify(this.lastMessage)); + localStorage.setItem('location', JSON.stringify(this.location)); + }, + getSavedData() { + let savedName = localStorage.getItem('name'); + + this.name = savedName ? savedName : this.name; + + let savedUsername = localStorage.getItem('username'); + this.username = savedUsername ? savedUsername : null; + + let savedActiveTheme = localStorage.getItem('activeTheme'); + this.activeTheme = savedActiveTheme ? savedActiveTheme : 'slate'; + + let savedMessages = JSON.parse(localStorage.getItem('messages')); + this.messages = savedMessages ? savedMessages : []; + + let savedAnswers = JSON.parse(localStorage.getItem('answers')); + this.answers = savedAnswers ? savedAnswers : []; + + let savedNotes = JSON.parse(localStorage.getItem('notes')); + this.notes = savedNotes ? savedNotes : []; + + let savedLastMessage = JSON.parse(localStorage.getItem('lastMessage')); + this.lastMessage = savedLastMessage ? savedLastMessage : null; + + let savedLocation = JSON.parse(localStorage.getItem('location')); + this.location = savedLocation ? savedLocation : null; + + this.scrollDown(); + }, + askForName() { + this.botMessage( + this.oneOf([ + 'May i ask for your name?', + 'Whats your name? :)', + 'How can i call you?', + 'How did your developers call you? :)' + ]) + ); + + this.askedForName = true; + }, + setName(message) { + this.username = message.trim(); + this.settingsModal.username = this.username; + this.askedForName = false; + this.updateStorage(); + + this.botMessage( + this.oneOf([ + "That's a beautiful name!", + "Okay, i'll call you " + this.username + " from now on :)", + "Nice to meet you, " + this.username + ". :D" + ]) + ) + }, + saveNote(message) { + this.takeNote = false; + + this.notes.push({ + time: moment(), + body: message, + checked: false + }); + + this.updateStorage(); + + this.botMessage( + this.oneOf([ + "Saved! :)", + "You can read and check your notes in the clipboard-section. :)" + ]) + ) + }, + clearNotes() { + this.notes = []; + + this.botMessage( + this.oneOf([ + "Notes cleared. ๐ฎ" + ]) + ); + + this.updateStorage(); + }, + saveSettings() { + this.name = this.settingsModal.name; + this.username = this.settingsModal.username; + this.location = this.settingsModal.location; + this.updateStorage(); + + // this.botMessage('Settings saved! :)'); + this.scrollDown(); + }, + clearChat() { + this.messages = []; + 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. โ'); + return; + } + + let city = this.location.toLowerCase(); + let url = 'http://api.openweathermap.org/data/2.5/weather?q=' + city + '&appid=8a1aa336da8899c1038bf6bd808d8961&units=metric'; + + 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 + '.'); + }) + .catch(function (error) { + alert(error); + 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(); + }, + meMessage(message) { + this.addMessage(this.username + ' ' + message, false, true); + this.react(message, true); + }, + clearStorage() { + localStorage.clear(); + location.reload(); + }, + getBootswatchThemes() { + let vue = this; + + axios.get('https://bootswatch.com/api/4.json') + .then(function (response) { + vue.themes = response.data.themes; + }) + .catch(function (error) { + console.log(error); + }) + } + } }) \ No newline at end of file diff --git a/index.html b/index.html index 4d69487..adde1c8 100644 --- a/index.html +++ b/index.html @@ -1,188 +1,184 @@ - - -
-