Browse Source

Initial commit

master
Nero Ignis 5 years ago
parent
commit
4762fd4292
  1. 1
      .idea/.name
  2. 8
      .idea/kara.iml
  3. 8
      .idea/modules.xml
  4. 61
      .idea/workspace.xml
  5. 30
      app.css
  6. 106
      app.js
  7. 67
      index.html

1
.idea/.name

@ -0,0 +1 @@ @@ -0,0 +1 @@
kara

8
.idea/kara.iml

@ -0,0 +1,8 @@ @@ -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>

8
.idea/modules.xml

@ -0,0 +1,8 @@ @@ -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>

61
.idea/workspace.xml

@ -0,0 +1,61 @@ @@ -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>

30
app.css

@ -0,0 +1,30 @@ @@ -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%
}

106
app.js

@ -0,0 +1,106 @@ @@ -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('…', '');
}
}
})

67
index.html

@ -0,0 +1,67 @@ @@ -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…
Cancel
Save