7 changed files with 281 additions and 0 deletions
@ -0,0 +1,8 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<module type="WEB_MODULE" version="4"> |
||||||
|
<component name="NewModuleRootManager"> |
||||||
|
<content url="file://$MODULE_DIR$" /> |
||||||
|
<orderEntry type="inheritedJdk" /> |
||||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||||
|
</component> |
||||||
|
</module> |
@ -0,0 +1,8 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="ProjectModuleManager"> |
||||||
|
<modules> |
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/kara.iml" filepath="$PROJECT_DIR$/.idea/kara.iml" /> |
||||||
|
</modules> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,61 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project version="4"> |
||||||
|
<component name="ChangeListManager"> |
||||||
|
<list default="true" id="e3f098f0-e98c-435a-af04-d153c9525633" name="Default Changelist" comment="" /> |
||||||
|
<option name="SHOW_DIALOG" value="false" /> |
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" /> |
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> |
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" /> |
||||||
|
</component> |
||||||
|
<component name="ComposerSettings"> |
||||||
|
<execution /> |
||||||
|
</component> |
||||||
|
<component name="PhpDebugGeneral" listening_started="true" /> |
||||||
|
<component name="ProjectId" id="1g0vdLKoCZC7Ep9S79Z434EvL8a" /> |
||||||
|
<component name="ProjectViewState"> |
||||||
|
<option name="hideEmptyMiddlePackages" value="true" /> |
||||||
|
<option name="showLibraryContents" value="true" /> |
||||||
|
</component> |
||||||
|
<component name="PropertiesComponent"> |
||||||
|
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> |
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" /> |
||||||
|
<property name="last.edited.regexp" value="Why, ever, would you? Stupid! pf." /> |
||||||
|
<property name="nodejs_package_manager_path" value="npm" /> |
||||||
|
<property name="settings.editor.selected.configurable" value="preferences.pluginManager" /> |
||||||
|
</component> |
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> |
||||||
|
<component name="TaskManager"> |
||||||
|
<task active="true" id="Default" summary="Default task"> |
||||||
|
<changelist id="e3f098f0-e98c-435a-af04-d153c9525633" name="Default Changelist" comment="" /> |
||||||
|
<created>1597264410641</created> |
||||||
|
<option name="number" value="Default" /> |
||||||
|
<option name="presentableId" value="Default" /> |
||||||
|
<updated>1597264410641</updated> |
||||||
|
<workItem from="1597264411672" duration="27000" /> |
||||||
|
<workItem from="1597264469454" duration="594000" /> |
||||||
|
<workItem from="1597346228730" duration="1396000" /> |
||||||
|
</task> |
||||||
|
<servers /> |
||||||
|
</component> |
||||||
|
<component name="TypeScriptGeneratedFilesManager"> |
||||||
|
<option name="version" value="3" /> |
||||||
|
</component> |
||||||
|
<component name="WindowStateProjectService"> |
||||||
|
<state x="172" y="0" key="SettingsEditor" timestamp="1597346967163"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="172" y="0" key="SettingsEditor/0.0.1366.720@0.0.1366.720" timestamp="1597346967163" /> |
||||||
|
<state x="0" y="0" width="616" height="720" key="find.popup" timestamp="1597346688624"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="0" y="0" width="616" height="720" key="find.popup/0.0.1366.720@0.0.1366.720" timestamp="1597346688624" /> |
||||||
|
<state width="533" height="302" key="javadoc.popup.new" timestamp="1597347220132"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state width="533" height="302" key="javadoc.popup.new/0.0.1366.720@0.0.1366.720" timestamp="1597347220132" /> |
||||||
|
<state x="346" y="41" width="672" height="678" key="search.everywhere.popup" timestamp="1597346938306"> |
||||||
|
<screen x="0" y="0" width="1366" height="720" /> |
||||||
|
</state> |
||||||
|
<state x="346" y="41" width="672" height="678" key="search.everywhere.popup/0.0.1366.720@0.0.1366.720" timestamp="1597346938306" /> |
||||||
|
</component> |
||||||
|
</project> |
@ -0,0 +1,30 @@ |
|||||||
|
#kara { |
||||||
|
margin: 2em auto auto auto; |
||||||
|
width: 50em; |
||||||
|
} |
||||||
|
|
||||||
|
#kara .card { |
||||||
|
height: 40em; |
||||||
|
} |
||||||
|
|
||||||
|
.message { |
||||||
|
padding: 10px; |
||||||
|
margin-bottom: 5px; |
||||||
|
min-width: 55%; |
||||||
|
max-width: 80%; |
||||||
|
} |
||||||
|
|
||||||
|
.ai-message { |
||||||
|
border-radius: 0px 15px 15px 15px; |
||||||
|
background-color: lightgreen; |
||||||
|
} |
||||||
|
|
||||||
|
.user-message { |
||||||
|
border-radius: 15px 0px 15px 15px; |
||||||
|
background-color: lightblue; |
||||||
|
} |
||||||
|
|
||||||
|
#chat-box { |
||||||
|
overflow-y: scroll; |
||||||
|
height: 100% |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
let kara = new Vue({ |
||||||
|
el: '#kara', |
||||||
|
data: { |
||||||
|
messages: [], |
||||||
|
name: 'Kara', |
||||||
|
chatbox: null, |
||||||
|
isTyping: false, |
||||||
|
templates: { |
||||||
|
initialGreeting: "Hi! I'm Kara. :)" |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.initialGreeting(); |
||||||
|
document.getElementById('chatinput').focus(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
addMessage(body, ai) { |
||||||
|
this.messages.push({ |
||||||
|
body: body, |
||||||
|
ai: ai, |
||||||
|
time: Date.now() |
||||||
|
}) |
||||||
|
}, |
||||||
|
aiMessage(body) { |
||||||
|
this.addMessage(body, true); |
||||||
|
}, |
||||||
|
userMessage(body) { |
||||||
|
this.addMessage(body, false); |
||||||
|
}, |
||||||
|
initialGreeting() { |
||||||
|
this.aiMessage(this.templates.initialGreeting); |
||||||
|
}, |
||||||
|
sendMessage() { |
||||||
|
this.userMessage(this.chatbox); |
||||||
|
this.react(this.chatbox); |
||||||
|
this.chatbox = ''; |
||||||
|
}, |
||||||
|
react(message) { |
||||||
|
this.isTyping = true; |
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
this.isTyping = false; |
||||||
|
document.getElementById('chatinput').focus(); |
||||||
|
}, 2500); |
||||||
|
|
||||||
|
setTimeout(() => { |
||||||
|
this.aiMessage( |
||||||
|
this.getAnswer(message) |
||||||
|
); |
||||||
|
}, 3000); |
||||||
|
|
||||||
|
this.scrollDown(); |
||||||
|
}, |
||||||
|
getAnswer(message) { |
||||||
|
let isQuestion = (message.indexOf('?') > 0); |
||||||
|
|
||||||
|
message = message.toLowerCase(); |
||||||
|
message = this.clearMessage(message); |
||||||
|
let phrases = message.split(' '); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isQuestion) { |
||||||
|
return 'This is a question!'; |
||||||
|
} else { |
||||||
|
if (message.indexOf('name') > 0) { |
||||||
|
return 'Nice to meet you!'; |
||||||
|
} else { |
||||||
|
return "I don't know what to say."; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return answer; |
||||||
|
}, |
||||||
|
scrollDown() { |
||||||
|
$('#chat-box').stop().animate({ |
||||||
|
scrollTop: $('#chat-box')[0].scrollHeight |
||||||
|
}, 800); |
||||||
|
}, |
||||||
|
clearMessage(message) { |
||||||
|
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('…', ''); |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
@ -0,0 +1,67 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<title> |
||||||
|
Kara AI |
||||||
|
</title> |
||||||
|
<link href="https://bootswatch.com/4/materia/bootstrap.min.css" rel="stylesheet" type="text/css"/> |
||||||
|
<link href="app.css" rel="stylesheet" type="text/css"/> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div class="container" id="kara"> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-md-12"> |
||||||
|
<div class="card"> |
||||||
|
<div class="card-header"> |
||||||
|
<h5 class="text-center"> |
||||||
|
Kara |
||||||
|
</h5> |
||||||
|
</div> |
||||||
|
<div class="card-body"> |
||||||
|
<div id="chat-box"> |
||||||
|
<template v-for="message in messages"> |
||||||
|
<div class="message ai-message float-left" v-if="message.ai"> |
||||||
|
{{ message.body }} |
||||||
|
<br/> |
||||||
|
</div> |
||||||
|
<div class="message user-message float-right" v-else=""> |
||||||
|
{{ message.body }} |
||||||
|
<br/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div class="message ai-message typing float-left" v-if="isTyping"> |
||||||
|
<div class="spinner-grow text-secondary" role="status"> |
||||||
|
<span class="sr-only"> |
||||||
|
Loading... |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
<div class="spinner-grow text-secondary" role="status"> |
||||||
|
<span class="sr-only"> |
||||||
|
Loading... |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
<div class="spinner-grow text-secondary" role="status"> |
||||||
|
<span class="sr-only"> |
||||||
|
Loading... |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="card-footer"> |
||||||
|
<input autofocus="true" class="form-control" id="chatinput" type="text" v-model="chatbox" v-on:keyup.enter="sendMessage()" v-if="!isTyping" autofocus> |
||||||
|
<input autofocus="true" class="form-control" id="chatinput" type="text" v-else disabled> |
||||||
|
</input> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<script src="https://code.jquery.com/jquery-3.5.1.js"> |
||||||
|
</script> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"> |
||||||
|
</script> |
||||||
|
<script src="app.js"> |
||||||
|
</script> |
||||||
|
</body> |
||||||
|
</html> |
Loading…
Reference in new issue