Deepti-AI commited on
Commit
45816aa
Β·
verified Β·
1 Parent(s): 650a8b1

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +165 -165
templates/index.html CHANGED
@@ -1,165 +1,165 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <title>Ortho Buddy β€” Voice</title>
6
- <style>
7
- html,body { height:100%; margin:0; font-family: "Segoe UI", Roboto, Arial; background: radial-gradient(circle at 50% 10%, #144a2b, #062219); color:#bfe6c9; }
8
- .container { width:360px; margin:40px auto; text-align:center; }
9
- h1 { letter-spacing:4px; font-size:36px; color:#2de08b; text-shadow:0 6px 30px rgba(0,0,0,0.7); margin:20px 0; }
10
- .subtitle { color:#d6f3de; margin-bottom:10px; font-size:24px; }
11
- .robot { width:270px; height:270px; background: url('robot.gif') center/contain no-repeat; margin: 40px auto; border-radius:8px; }
12
- .control { margin-top:20px; }
13
- .record-btn { width:50px; height:50px; border-radius:60px; border:none; background:linear-gradient(rgb(248, 245, 248), rgb(248, 245, 248)); box-shadow: 0 10px 30px rgba(0,0,0,0.6); color:white; font-size:18px; cursor:pointer; }
14
- .record-btn.recording { background: linear-gradient(#ff6666, #cc2222); box-shadow: 0 10px 30px rgba(0,0,0,0.7); }
15
- .heading {
16
- text-align: center;
17
- }
18
- .reset-btn {
19
- position: fixed;
20
- top: 20px;
21
- right: 20px;
22
- padding: 10px 20px;
23
- background: linear-gradient(#2de08b, #0a8f5c);
24
- border: none;
25
- border-radius: 6px;
26
- font-size: 16px;
27
- font-weight: bold;
28
- color: #062219;
29
- cursor: pointer;
30
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
31
- z-index: 1000;
32
- transition: background 0.3s ease;
33
- }
34
-
35
- .reset-btn:hover {
36
- background: linear-gradient(#1bc47a, #07734f);
37
- }
38
-
39
- </style>
40
- <h1 class = "heading">Summit Dental & Orthopedics</h1>
41
- </head>
42
- <body>
43
- <div class="container">
44
-
45
- <div class="subtitle"><b>KAMMI</b></div>
46
-
47
- <div class="robot" id="robotImg"></div>
48
-
49
- <div class="control">
50
- <button id="recBtn" class="record-btn">🎀</button>
51
- </div>
52
-
53
- <button id="resetBtn" class="reset-btn">New User</button>
54
-
55
- <div class="text-stream" id="textStream"></div>
56
-
57
- <!-- Hidden audio player for streamed voice -->
58
- <audio id="player" controls autoplay hidden></audio>
59
- </div>
60
-
61
- <script>
62
- let mediaRecorder;
63
- let audioChunks = [];
64
- let recBtn = document.getElementById("recBtn");
65
- let textStream = document.getElementById("textStream");
66
- let recording = false;
67
- let player = document.getElementById("player");
68
-
69
- document.getElementById("resetBtn").addEventListener("click", async () => {
70
- try {
71
- const response = await fetch("http://127.0.0.1:8000/reset_chat", {
72
- method: "POST"
73
- });
74
-
75
- if (response.ok) {
76
- showTempMessage("Please proceed.", "lightgreen");
77
- } else {
78
- const errorText = await response.text();
79
- showTempMessage("Reset failed: " + errorText, "#ffb3b3");
80
- }
81
- } catch (error) {
82
- showTempMessage("Reset error: " + error.message, "#ffb3b3");
83
- }
84
- });
85
-
86
- // Utility function to show a message for 2 seconds
87
- function showTempMessage(msg, color) {
88
- const msgDiv = document.createElement("div");
89
- msgDiv.style.color = color;
90
- msgDiv.textContent = msg;
91
- textStream.appendChild(msgDiv);
92
-
93
- setTimeout(() => {
94
- msgDiv.remove();
95
- }, 2000);
96
- }
97
-
98
-
99
- recBtn.addEventListener("click", async () => {
100
- if (!recording) {
101
- await startRecording();
102
- } else {
103
- stopRecordingAndSend();
104
- }
105
- recording = !recording;
106
- recBtn.textContent = recording ? "Stop" : "🎀";
107
- recBtn.classList.toggle("recording", recording);
108
- });
109
-
110
- async function startRecording() {
111
- textStream.innerHTML = ""; // clear previous
112
- audioChunks = [];
113
- if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
114
- alert("Your browser does not support microphone capture.");
115
- return;
116
- }
117
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
118
- mediaRecorder = new MediaRecorder(stream);
119
- mediaRecorder.ondataavailable = e => {
120
- if (e.data && e.data.size > 0) audioChunks.push(e.data);
121
- };
122
- mediaRecorder.start();
123
- }
124
-
125
- function stopRecordingAndSend() {
126
- if (!mediaRecorder) return;
127
- mediaRecorder.stop();
128
- mediaRecorder.onstop = async () => {
129
- const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
130
- const form = new FormData();
131
- form.append("file", audioBlob, "recording.webm");
132
-
133
- // fetch streaming audio directly
134
- console.log("Sending audio to server...");
135
- const resp = await fetch("http://127.0.0.1:8000/chat_stream", {
136
- method: "POST",
137
- body: form,
138
- });
139
-
140
- if (!resp.ok) {
141
- const txt = await resp.text();
142
- textStream.innerHTML += "<div style='color:#ffb3b3'>Server error: " + txt + "</div>";
143
- return;
144
- }
145
-
146
- // create an object URL from streaming response
147
- const mediaSource = new MediaSource();
148
- player.src = URL.createObjectURL(mediaSource);
149
- mediaSource.addEventListener('sourceopen', async () => {
150
- const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
151
- const reader = resp.body.getReader();
152
- while (true) {
153
- const { done, value } = await reader.read();
154
- if (done) break;
155
- sourceBuffer.appendBuffer(value);
156
- await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }));
157
- }
158
- mediaSource.endOfStream();
159
- });
160
- player.play();
161
- };
162
- }
163
- </script>
164
- </body>
165
- </html>
 
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Ortho Buddy β€” Voice</title>
6
+ <style>
7
+ html,body { height:100%; margin:0; font-family: "Segoe UI", Roboto, Arial; background: radial-gradient(circle at 50% 10%, #144a2b, #062219); color:#bfe6c9; }
8
+ .container { width:360px; margin:40px auto; text-align:center; }
9
+ h1 { letter-spacing:4px; font-size:36px; color:#2de08b; text-shadow:0 6px 30px rgba(0,0,0,0.7); margin:20px 0; }
10
+ .subtitle { color:#d6f3de; margin-bottom:10px; font-size:24px; }
11
+ .robot { width:270px; height:270px; background: url('/static/robot.gif') center/contain no-repeat; margin: 40px auto; border-radius:8px; }
12
+ .control { margin-top:20px; }
13
+ .record-btn { width:50px; height:50px; border-radius:60px; border:none; background:linear-gradient(rgb(248, 245, 248), rgb(248, 245, 248)); box-shadow: 0 10px 30px rgba(0,0,0,0.6); color:white; font-size:18px; cursor:pointer; }
14
+ .record-btn.recording { background: linear-gradient(#ff6666, #cc2222); box-shadow: 0 10px 30px rgba(0,0,0,0.7); }
15
+ .heading {
16
+ text-align: center;
17
+ }
18
+ .reset-btn {
19
+ position: fixed;
20
+ top: 20px;
21
+ right: 20px;
22
+ padding: 10px 20px;
23
+ background: linear-gradient(#2de08b, #0a8f5c);
24
+ border: none;
25
+ border-radius: 6px;
26
+ font-size: 16px;
27
+ font-weight: bold;
28
+ color: #062219;
29
+ cursor: pointer;
30
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
31
+ z-index: 1000;
32
+ transition: background 0.3s ease;
33
+ }
34
+
35
+ .reset-btn:hover {
36
+ background: linear-gradient(#1bc47a, #07734f);
37
+ }
38
+
39
+ </style>
40
+ <h1 class = "heading">Summit Dental & Orthopedics</h1>
41
+ </head>
42
+ <body>
43
+ <div class="container">
44
+
45
+ <div class="subtitle"><b>KAMMI</b></div>
46
+
47
+ <div class="robot" id="robotImg"></div>
48
+
49
+ <div class="control">
50
+ <button id="recBtn" class="record-btn">🎀</button>
51
+ </div>
52
+
53
+ <button id="resetBtn" class="reset-btn">New User</button>
54
+
55
+ <div class="text-stream" id="textStream"></div>
56
+
57
+ <!-- Hidden audio player for streamed voice -->
58
+ <audio id="player" controls autoplay hidden></audio>
59
+ </div>
60
+
61
+ <script>
62
+ let mediaRecorder;
63
+ let audioChunks = [];
64
+ let recBtn = document.getElementById("recBtn");
65
+ let textStream = document.getElementById("textStream");
66
+ let recording = false;
67
+ let player = document.getElementById("player");
68
+
69
+ document.getElementById("resetBtn").addEventListener("click", async () => {
70
+ try {
71
+ const response = await fetch("/reset_chat", {
72
+ method: "POST"
73
+ });
74
+
75
+ if (response.ok) {
76
+ showTempMessage("Please proceed.", "lightgreen");
77
+ } else {
78
+ const errorText = await response.text();
79
+ showTempMessage("Reset failed: " + errorText, "#ffb3b3");
80
+ }
81
+ } catch (error) {
82
+ showTempMessage("Reset error: " + error.message, "#ffb3b3");
83
+ }
84
+ });
85
+
86
+ // Utility function to show a message for 2 seconds
87
+ function showTempMessage(msg, color) {
88
+ const msgDiv = document.createElement("div");
89
+ msgDiv.style.color = color;
90
+ msgDiv.textContent = msg;
91
+ textStream.appendChild(msgDiv);
92
+
93
+ setTimeout(() => {
94
+ msgDiv.remove();
95
+ }, 2000);
96
+ }
97
+
98
+
99
+ recBtn.addEventListener("click", async () => {
100
+ if (!recording) {
101
+ await startRecording();
102
+ } else {
103
+ stopRecordingAndSend();
104
+ }
105
+ recording = !recording;
106
+ recBtn.textContent = recording ? "Stop" : "🎀";
107
+ recBtn.classList.toggle("recording", recording);
108
+ });
109
+
110
+ async function startRecording() {
111
+ textStream.innerHTML = ""; // clear previous
112
+ audioChunks = [];
113
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
114
+ alert("Your browser does not support microphone capture.");
115
+ return;
116
+ }
117
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
118
+ mediaRecorder = new MediaRecorder(stream);
119
+ mediaRecorder.ondataavailable = e => {
120
+ if (e.data && e.data.size > 0) audioChunks.push(e.data);
121
+ };
122
+ mediaRecorder.start();
123
+ }
124
+
125
+ function stopRecordingAndSend() {
126
+ if (!mediaRecorder) return;
127
+ mediaRecorder.stop();
128
+ mediaRecorder.onstop = async () => {
129
+ const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
130
+ const form = new FormData();
131
+ form.append("file", audioBlob, "recording.webm");
132
+
133
+ // fetch streaming audio directly
134
+ console.log("Sending audio to server...");
135
+ const resp = await fetch("/chat_stream", {
136
+ method: "POST",
137
+ body: form,
138
+ });
139
+
140
+ if (!resp.ok) {
141
+ const txt = await resp.text();
142
+ textStream.innerHTML += "<div style='color:#ffb3b3'>Server error: " + txt + "</div>";
143
+ return;
144
+ }
145
+
146
+ // create an object URL from streaming response
147
+ const mediaSource = new MediaSource();
148
+ player.src = URL.createObjectURL(mediaSource);
149
+ mediaSource.addEventListener('sourceopen', async () => {
150
+ const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
151
+ const reader = resp.body.getReader();
152
+ while (true) {
153
+ const { done, value } = await reader.read();
154
+ if (done) break;
155
+ sourceBuffer.appendBuffer(value);
156
+ await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }));
157
+ }
158
+ mediaSource.endOfStream();
159
+ });
160
+ player.play();
161
+ };
162
+ }
163
+ </script>
164
+ </body>
165
+ </html>