awacke1 commited on
Commit
676cc2e
·
verified ·
1 Parent(s): 59d1be3

Create mycomponent/index.html

Browse files
Files changed (1) hide show
  1. mycomponent/index.html +195 -0
mycomponent/index.html ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <style>
5
+ .speech-container {
6
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
7
+ padding: 20px;
8
+ border-radius: 10px;
9
+ background: white;
10
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
11
+ }
12
+
13
+ .controls {
14
+ display: flex;
15
+ gap: 10px;
16
+ margin-bottom: 15px;
17
+ }
18
+
19
+ button {
20
+ padding: 8px 16px;
21
+ border-radius: 5px;
22
+ border: none;
23
+ background: #2196F3;
24
+ color: white;
25
+ cursor: pointer;
26
+ transition: background 0.3s;
27
+ }
28
+
29
+ button:disabled {
30
+ background: #ccc;
31
+ cursor: not-allowed;
32
+ }
33
+
34
+ button:hover:not(:disabled) {
35
+ background: #1976D2;
36
+ }
37
+
38
+ #status {
39
+ margin: 10px 0;
40
+ padding: 10px;
41
+ border-radius: 5px;
42
+ background: #E3F2FD;
43
+ }
44
+
45
+ #output {
46
+ margin-top: 15px;
47
+ padding: 15px;
48
+ border-radius: 5px;
49
+ background: #F5F5F5;
50
+ min-height: 100px;
51
+ max-height: 300px;
52
+ overflow-y: auto;
53
+ white-space: pre-wrap;
54
+ }
55
+ </style>
56
+ </head>
57
+ <body>
58
+ <div class="speech-container">
59
+ <div class="controls">
60
+ <button id="start">Start Listening</button>
61
+ <button id="stop" disabled>Stop</button>
62
+ <button id="clear">Clear</button>
63
+ </div>
64
+ <div id="status">Ready</div>
65
+ <div id="output"></div>
66
+ </div>
67
+
68
+ <script>
69
+ // Streamlit Component Initialization
70
+ function sendMessageToStreamlit(type, data) {
71
+ const outData = Object.assign({
72
+ isStreamlitMessage: true,
73
+ type: type,
74
+ }, data);
75
+ window.parent.postMessage(outData, "*");
76
+ }
77
+
78
+ function init() {
79
+ sendMessageToStreamlit("streamlit:componentReady", {apiVersion: 1});
80
+ }
81
+
82
+ function setFrameHeight(height) {
83
+ sendMessageToStreamlit("streamlit:setFrameHeight", {height: height});
84
+ }
85
+
86
+ function sendDataToStreamlit(data) {
87
+ sendMessageToStreamlit("streamlit:setComponentValue", data);
88
+ }
89
+
90
+ // Speech Recognition Setup
91
+ if (!('webkitSpeechRecognition' in window)) {
92
+ document.getElementById('status').textContent = 'Speech recognition not supported';
93
+ } else {
94
+ const recognition = new webkitSpeechRecognition();
95
+ const startButton = document.getElementById('start');
96
+ const stopButton = document.getElementById('stop');
97
+ const clearButton = document.getElementById('clear');
98
+ const status = document.getElementById('status');
99
+ const output = document.getElementById('output');
100
+
101
+ let fullTranscript = '';
102
+ let lastUpdate = Date.now();
103
+
104
+ recognition.continuous = true;
105
+ recognition.interimResults = true;
106
+
107
+ startButton.onclick = () => {
108
+ try {
109
+ recognition.start();
110
+ status.textContent = 'Listening...';
111
+ startButton.disabled = true;
112
+ stopButton.disabled = false;
113
+ } catch (e) {
114
+ console.error('Recognition error:', e);
115
+ status.textContent = 'Error: ' + e.message;
116
+ }
117
+ };
118
+
119
+ stopButton.onclick = () => {
120
+ recognition.stop();
121
+ status.textContent = 'Stopped';
122
+ startButton.disabled = false;
123
+ stopButton.disabled = true;
124
+ };
125
+
126
+ clearButton.onclick = () => {
127
+ fullTranscript = '';
128
+ output.textContent = '';
129
+ sendDataToStreamlit({
130
+ value: '',
131
+ dataType: "json",
132
+ });
133
+ };
134
+
135
+ recognition.onresult = (event) => {
136
+ let interimTranscript = '';
137
+ let finalTranscript = '';
138
+
139
+ for (let i = event.resultIndex; i < event.results.length; i++) {
140
+ const transcript = event.results[i][0].transcript;
141
+ if (event.results[i].isFinal) {
142
+ finalTranscript += transcript + '\n';
143
+ } else {
144
+ interimTranscript += transcript;
145
+ }
146
+ }
147
+
148
+ if (finalTranscript || (Date.now() - lastUpdate > 3000)) {
149
+ if (finalTranscript) {
150
+ fullTranscript += finalTranscript;
151
+ sendDataToStreamlit({
152
+ value: fullTranscript,
153
+ dataType: "json",
154
+ });
155
+ }
156
+ lastUpdate = Date.now();
157
+ }
158
+
159
+ output.textContent = fullTranscript + (interimTranscript ? '... ' + interimTranscript : '');
160
+ output.scrollTop = output.scrollHeight;
161
+ };
162
+
163
+ recognition.onend = () => {
164
+ if (!stopButton.disabled) {
165
+ try {
166
+ recognition.start();
167
+ } catch (e) {
168
+ console.error('Failed to restart recognition:', e);
169
+ status.textContent = 'Error restarting: ' + e.message;
170
+ startButton.disabled = false;
171
+ stopButton.disabled = true;
172
+ }
173
+ }
174
+ };
175
+
176
+ recognition.onerror = (event) => {
177
+ console.error('Recognition error:', event.error);
178
+ status.textContent = 'Error: ' + event.error;
179
+ if (event.error === 'not-allowed') {
180
+ startButton.disabled = false;
181
+ stopButton.disabled = true;
182
+ }
183
+ };
184
+ }
185
+
186
+ // Initialize component
187
+ init();
188
+
189
+ // Set initial height
190
+ window.addEventListener("load", () => {
191
+ setFrameHeight(document.documentElement.scrollHeight);
192
+ });
193
+ </script>
194
+ </body>
195
+ </html>