├── .editorconfig
├── .gitattributes
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── LICENSE
├── README.md
├── bot.html
└── static
├── img
├── bot.jpg
├── demo.png
└── guy.jpg
├── main.css
└── main.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 | indent_style = tab
11 | indent_size = 4
12 | max_line_length = 120
13 |
14 | [*.md]
15 | trim_trailing_whitespace = false
16 | max_line_length = 0
17 |
18 | [{**.min.**, **/vendors/**}]
19 | charset = unset
20 | end_of_line = unset
21 | insert_final_newline = unset
22 | trim_trailing_whitespace = unset
23 | indent_style = unset
24 | indent_size = unset
25 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | **/vendors/**
2 | **.min.**
3 | *.py
4 | *.md
5 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 4,
3 | "useTabs": true,
4 | "semi": true,
5 | "singleQuote": true,
6 | "trailingComma": "all",
7 | "bracketSpacing": true,
8 | "jsxBracketSameLine": false,
9 | "insertPragma": false
10 | }
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Thomas Ashish Cherian
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Chatbot Frontend
2 | A simple chatbot frontend for plugging in my bots.
3 |
4 | To add a user message to the chat window
5 | run javascript function -
6 |
7 | showUserMessage("Message",getCurrentTimestamp());
8 |
9 | To add a bot message to the chat window
10 | run javascript function -
11 |
12 | showBotMessage("Message",getCurrentTimestamp());
13 |
14 | ## Screenshot
15 | 
16 |
17 | PR's are welcome :)
18 |
--------------------------------------------------------------------------------
/bot.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Chatbot Frontend
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
71 |
72 |
73 | Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
74 | mollit anim id est laborum
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/static/img/bot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PandaWhoCodes/chatbot-frontend/1b1ebb51cd7b4bbeaee5d3fefadb5c533b1abb18/static/img/bot.jpg
--------------------------------------------------------------------------------
/static/img/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PandaWhoCodes/chatbot-frontend/1b1ebb51cd7b4bbeaee5d3fefadb5c533b1abb18/static/img/demo.png
--------------------------------------------------------------------------------
/static/img/guy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PandaWhoCodes/chatbot-frontend/1b1ebb51cd7b4bbeaee5d3fefadb5c533b1abb18/static/img/guy.jpg
--------------------------------------------------------------------------------
/static/main.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | body {
6 | background-color: #edeff2;
7 | font-family: 'Calibri', 'Roboto', sans-serif;
8 | }
9 |
10 | .row.padded_row,
11 | .row.padded_row > div {
12 | padding-top: 20px;
13 | padding-bottom: 20px;
14 | }
15 |
16 | /* layout and common global classes */
17 | /* ---------------------------------------------------------------------- */
18 |
19 | .chat_window {
20 | border-radius: 10px;
21 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
22 | background-color: #f8f8f8;
23 | overflow: hidden;
24 | }
25 |
26 | .top_menu {
27 | background-color: #fff;
28 | padding: 13px 0px;
29 | box-shadow: 0 1px 30px rgba(0, 0, 0, 0.1);
30 | }
31 |
32 | .top_menu .title {
33 | text-align: center;
34 | color: #337ab7;
35 | font-size: 20px;
36 | }
37 |
38 | /* messages inside the chatbox */
39 | /* ---------------------------------------------------------------------- */
40 |
41 | .messages {
42 | position: relative;
43 | list-style: none;
44 | padding: 20px 10px 0 10px;
45 | margin: 0;
46 | height: 500px;
47 | overflow: scroll;
48 | }
49 |
50 | .messages .message {
51 | clear: both;
52 | overflow: hidden;
53 | margin-bottom: 20px;
54 | transition: all 0.5s linear;
55 | opacity: 0;
56 | }
57 |
58 | .messages .message .avatar {
59 | height: 40px;
60 | width: 40px;
61 | background-size: cover !important;
62 | border-radius: 50%;
63 | display: inline-block;
64 | }
65 |
66 | .messages .message .timestamp {
67 | font-size: 10px;
68 | font-weight: 300;
69 | text-align: right;
70 | margin-top: 5px;
71 | }
72 |
73 | .messages .message.appeared {
74 | opacity: 1;
75 | }
76 |
77 | .messages .message .text_wrapper {
78 | display: inline-block;
79 | padding: 20px;
80 | border-radius: 6px;
81 | min-width: 150px;
82 | position: relative;
83 | }
84 |
85 | .messages .message .text_wrapper::after,
86 | .messages .message .text_wrapper:before {
87 | top: 18px;
88 | border: solid transparent;
89 | content: ' ';
90 | height: 0;
91 | width: 0;
92 | position: absolute;
93 | pointer-events: none;
94 | }
95 |
96 | .messages .message .text_wrapper::after {
97 | border-width: 13px;
98 | margin-top: 0px;
99 | }
100 |
101 | .messages .message .text_wrapper::before {
102 | border-width: 15px;
103 | margin-top: -2px;
104 | }
105 |
106 | /* bot message */
107 |
108 | .messages .message.left .avatar {
109 | float: left;
110 | background: url('./img/bot.jpg');
111 | }
112 |
113 | .messages .message.left .text_wrapper {
114 | background-color: #f3eeca;
115 | margin-left: 20px;
116 | }
117 |
118 | .messages .message.left .text_wrapper::after,
119 | .messages .message.left .text_wrapper::before {
120 | right: 100%;
121 | border-right-color: #f3eeca;
122 | }
123 |
124 | .messages .message.left .timestamp {
125 | color: #b0742f;
126 | }
127 |
128 | /* user message */
129 |
130 | .messages .message.right .avatar {
131 | float: right;
132 | background: url('./img/guy.jpg');
133 | }
134 |
135 | .messages .message.right .text_wrapper {
136 | background-color: #b0d4f3;
137 | margin-right: 20px;
138 | float: right;
139 | }
140 |
141 | .messages .message.right .text_wrapper::after,
142 | .messages .message.right .text_wrapper::before {
143 | left: 100%;
144 | border-left-color: #b0d4f3;
145 | }
146 |
147 | .messages .message.right .timestamp {
148 | color: #1a5770;
149 | }
150 |
151 | /* text inpur from user */
152 |
153 | .bottom_wrapper {
154 | background-color: #fff;
155 | padding: 20px;
156 | bottom: 0;
157 | display: flex;
158 | }
159 |
160 | .bottom_wrapper #msg_input {
161 | flex-grow: 1;
162 | outline-width: 0;
163 | padding: 12px;
164 | border: 1px solid #bcbdc0;
165 | border-radius: 50px;
166 | margin-right: 15px;
167 | }
168 |
169 | .app_button_1 {
170 | width: 140px;
171 | background-color: #a3d063;
172 | border-radius: 50px;
173 | cursor: pointer;
174 | padding: 12px;
175 |
176 | color: #fff;
177 | font-size: 18px;
178 | font-weight: 300;
179 | text-align: center;
180 | }
181 |
182 | /* faq section | right side */
183 | /* ---------------------------------------------------------------------- */
184 |
185 | .panel-group {
186 | margin: 20px;
187 | }
188 |
189 | .panel-heading [data-toggle='collapse']:after {
190 | font-family: 'FontAwesome';
191 | content: '\f054';
192 | float: right;
193 | font-size: 18px;
194 | line-height: 22px;
195 | transition: all 0.2s linear;
196 |
197 | -webkit-transform: rotate(-90deg);
198 | -moz-transform: rotate(-90deg);
199 | -ms-transform: rotate(-90deg);
200 | -o-transform: rotate(-90deg);
201 | transform: rotate(-90deg);
202 | }
203 |
204 | .panel-heading [data-toggle='collapse'].collapsed:after {
205 | -webkit-transform: rotate(90deg);
206 | -moz-transform: rotate(90deg);
207 | -ms-transform: rotate(90deg);
208 | -o-transform: rotate(90deg);
209 | transform: rotate(90deg);
210 | }
211 |
--------------------------------------------------------------------------------
/static/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the current datetime for the message creation.
3 | */
4 | function getCurrentTimestamp() {
5 | return new Date();
6 | }
7 |
8 | /**
9 | * Renders a message on the chat screen based on the given arguments.
10 | * This is called from the `showUserMessage` and `showBotMessage`.
11 | */
12 | function renderMessageToScreen(args) {
13 | // local variables
14 | let displayDate = (args.time || getCurrentTimestamp()).toLocaleString('en-IN', {
15 | month: 'short',
16 | day: 'numeric',
17 | hour: 'numeric',
18 | minute: 'numeric',
19 | });
20 | let messagesContainer = $('.messages');
21 |
22 | // init element
23 | let message = $(`
24 |
25 |
26 |
27 |
${args.text}
28 |
${displayDate}
29 |
30 |
31 | `);
32 |
33 | // add to parent
34 | messagesContainer.append(message);
35 |
36 | // animations
37 | setTimeout(function () {
38 | message.addClass('appeared');
39 | }, 0);
40 | messagesContainer.animate({ scrollTop: messagesContainer.prop('scrollHeight') }, 300);
41 | }
42 |
43 | /* Sends a message when the 'Enter' key is pressed.
44 | */
45 | $(document).ready(function() {
46 | $('#msg_input').keydown(function(e) {
47 | // Check for 'Enter' key
48 | if (e.key === 'Enter') {
49 | // Prevent default behaviour of enter key
50 | e.preventDefault();
51 | // Trigger send button click event
52 | $('#send_button').click();
53 | }
54 | });
55 | });
56 |
57 | /**
58 | * Displays the user message on the chat screen. This is the right side message.
59 | */
60 | function showUserMessage(message, datetime) {
61 | renderMessageToScreen({
62 | text: message,
63 | time: datetime,
64 | message_side: 'right',
65 | });
66 | }
67 |
68 | /**
69 | * Displays the chatbot message on the chat screen. This is the left side message.
70 | */
71 | function showBotMessage(message, datetime) {
72 | renderMessageToScreen({
73 | text: message,
74 | time: datetime,
75 | message_side: 'left',
76 | });
77 | }
78 |
79 | /**
80 | * Get input from user and show it on screen on button click.
81 | */
82 | $('#send_button').on('click', function (e) {
83 | // get and show message and reset input
84 | showUserMessage($('#msg_input').val());
85 | $('#msg_input').val('');
86 |
87 | // show bot message
88 | setTimeout(function () {
89 | showBotMessage(randomstring());
90 | }, 300);
91 | });
92 |
93 | /**
94 | * Returns a random string. Just to specify bot message to the user.
95 | */
96 | function randomstring(length = 20) {
97 | let output = '';
98 |
99 | // magic function
100 | var randomchar = function () {
101 | var n = Math.floor(Math.random() * 62);
102 | if (n < 10) return n;
103 | if (n < 36) return String.fromCharCode(n + 55);
104 | return String.fromCharCode(n + 61);
105 | };
106 |
107 | while (output.length < length) output += randomchar();
108 | return output;
109 | }
110 |
111 | /**
112 | * Set initial bot message to the screen for the user.
113 | */
114 | $(window).on('load', function () {
115 | showBotMessage('Hello there! Type in a message.');
116 | });
--------------------------------------------------------------------------------