let kara = new Vue({ el: '#kara', data: { messages: [], lastMessage: null, name: 'Kara', location: null, chatbox: null, isTyping: false, askedForName: false, takeNote: false, username: '', themes: null, activeTheme: 'slate', 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(); this.getBootswatchThemes(); this.settingsModal = { name: this.name, username: this.username, location: this.location }; if (!this.username || this.username === "null") { this.initialGreeting(); this.askForName(); this.isTyping = false; } else { this.welcomeBack(); } document.getElementById('chatinput').focus(); document.title = this.name; this.scrollDown(); }, methods: { addMessage(body, bot) { this.messages.push({ body: body, bot: bot, time: Date.now() }) }, botMessage(body) { this.addMessage(body, true); }, 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; } this.userMessage(this.chatbox); this.scrollDown(); this.react(this.chatbox); this.chatbox = ''; }, react(message) { this.isTyping = true; setTimeout(() => { // Check commands if (this.checkForCommands(message, ['note', 'nt'])) { 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); } this.updateStorage(); } this.isTyping = false; this.scrollDown(); }, 2000); }, 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; }, 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('?', '') .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.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, ['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, ['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. :)" ]) ) }, 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('Chat cleared.'); 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) { console.log(error); vue.botMessage('I couldn\'t check the weather for your location.'); }) this.updateStorage(); }, 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); }) } } })