iisadia commited on
Commit
96c3bdf
·
verified ·
1 Parent(s): 6a60611

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -26
app.py CHANGED
@@ -5,6 +5,70 @@ from streamlit.components.v1 import html
5
  import os
6
  from dotenv import load_dotenv
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  # Import transformers and cache the help agent for performance
9
  @st.cache_resource
10
  def get_help_agent():
@@ -18,15 +82,12 @@ def inject_custom_css():
18
  <style>
19
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
20
  @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css');
21
-
22
  * {
23
  font-family: 'Inter', sans-serif;
24
  }
25
-
26
  body {
27
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
28
  }
29
-
30
  .title {
31
  font-size: 2.8rem !important;
32
  font-weight: 800 !important;
@@ -37,7 +98,6 @@ def inject_custom_css():
37
  margin: 1rem 0;
38
  letter-spacing: -1px;
39
  }
40
-
41
  .subtitle {
42
  font-size: 1.1rem !important;
43
  text-align: center;
@@ -45,7 +105,6 @@ def inject_custom_css():
45
  margin-bottom: 2.5rem;
46
  animation: fadeInSlide 1s ease;
47
  }
48
-
49
  .question-box {
50
  background: white;
51
  border-radius: 20px;
@@ -57,11 +116,9 @@ def inject_custom_css():
57
  transition: transform 0.2s ease;
58
  color: black;
59
  }
60
-
61
  .question-box:hover {
62
  transform: translateY(-3px);
63
  }
64
-
65
  .question-box::before {
66
  content: "🕹️";
67
  position: absolute;
@@ -73,7 +130,6 @@ def inject_custom_css():
73
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
74
  font-size: 1.2rem;
75
  }
76
-
77
  .input-box {
78
  background: white;
79
  border-radius: 12px;
@@ -81,19 +137,16 @@ def inject_custom_css():
81
  margin: 1rem 0;
82
  box-shadow: 0 4px 6px rgba(0,0,0,0.05);
83
  }
84
-
85
  .stTextInput input {
86
  border: 2px solid #e2e8f0 !important;
87
  border-radius: 10px !important;
88
  padding: 12px 16px !important;
89
  transition: all 0.3s ease !important;
90
  }
91
-
92
  .stTextInput input:focus {
93
  border-color: #6C63FF !important;
94
  box-shadow: 0 0 0 3px rgba(108, 99, 255, 0.2) !important;
95
  }
96
-
97
  button {
98
  background: linear-gradient(45deg, #6C63FF, #3B82F6) !important;
99
  color: white !important;
@@ -103,12 +156,10 @@ def inject_custom_css():
103
  font-weight: 600 !important;
104
  transition: all 0.3s ease !important;
105
  }
106
-
107
  button:hover {
108
  transform: translateY(-2px);
109
  box-shadow: 0 5px 15px rgba(108, 99, 255, 0.3) !important;
110
  }
111
-
112
  .final-reveal {
113
  animation: fadeInUp 1s ease;
114
  font-size: 2.8rem;
@@ -119,7 +170,6 @@ def inject_custom_css():
119
  margin: 2rem 0;
120
  font-weight: 800;
121
  }
122
-
123
  .help-chat {
124
  background: rgba(255,255,255,0.9);
125
  backdrop-filter: blur(10px);
@@ -128,17 +178,14 @@ def inject_custom_css():
128
  margin: 1rem 0;
129
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
130
  }
131
-
132
  @keyframes fadeInSlide {
133
  0% { opacity: 0; transform: translateY(20px); }
134
  100% { opacity: 1; transform: translateY(0); }
135
  }
136
-
137
  @keyframes fadeInUp {
138
  0% { opacity: 0; transform: translateY(30px); }
139
  100% { opacity: 1; transform: translateY(0); }
140
  }
141
-
142
  .progress-bar {
143
  height: 6px;
144
  background: #e2e8f0;
@@ -146,13 +193,11 @@ def inject_custom_css():
146
  margin: 1.5rem 0;
147
  overflow: hidden;
148
  }
149
-
150
  .progress-fill {
151
  height: 100%;
152
  background: linear-gradient(90deg, #6C63FF, #3B82F6);
153
  transition: width 0.5s ease;
154
  }
155
-
156
  .question-count {
157
  color: #6C63FF;
158
  font-weight: 600;
@@ -173,13 +218,11 @@ def show_confetti():
173
  origin: { y: 0.7 },
174
  zIndex: 1050
175
  };
176
-
177
  function fire(particleRatio, opts) {
178
  confetti(Object.assign({}, defaults, opts, {
179
  particleCount: Math.floor(count * particleRatio)
180
  }));
181
  }
182
-
183
  fire(0.25, { spread: 26, startVelocity: 55 });
184
  fire(0.2, { spread: 60 });
185
  fire(0.35, { spread: 100, decay: 0.91, scalar: 0.8 });
@@ -277,7 +320,6 @@ def ask_help_agent(query):
277
  except Exception as e:
278
  return f"Error in help agent: {str(e)}"
279
 
280
-
281
  # Main game logic with enhanced UI
282
  def main():
283
  inject_custom_css()
@@ -323,7 +365,13 @@ def main():
323
  """, unsafe_allow_html=True)
324
 
325
  with st.form("start_form"):
326
- category_input = st.text_input("Enter category (person/place/object):").strip().lower()
 
 
 
 
 
 
327
  if st.form_submit_button("Start Game"):
328
  if not category_input:
329
  st.error("Please enter a category!")
@@ -376,8 +424,14 @@ def main():
376
  st.experimental_rerun()
377
 
378
  with st.form("answer_form"):
379
- answer_input = st.text_input("Your answer (yes/no/both):",
380
- key=f"answer_{st.session_state.current_q}").strip().lower()
 
 
 
 
 
 
381
  if st.form_submit_button("Submit"):
382
  if answer_input not in ["yes", "no", "both"]:
383
  st.error("Please answer with 'yes', 'no', or 'both'!")
@@ -442,7 +496,13 @@ def main():
442
  ''', unsafe_allow_html=True)
443
 
444
  with st.form("confirm_form"):
445
- confirm_input = st.text_input("Type your answer (yes/no/both):", key="confirm_input").strip().lower()
 
 
 
 
 
 
446
  if st.form_submit_button("Submit"):
447
  if confirm_input not in ["yes", "no", "both"]:
448
  st.error("Please answer with 'yes', 'no', or 'both'!")
 
5
  import os
6
  from dotenv import load_dotenv
7
 
8
+ # Speech recognition component
9
+ def add_mic_button(target_input_key, is_select=False):
10
+ html(f"""
11
+ <script>
12
+ function startSpeechRecognition{target_input_key}() {{
13
+ const targetElem = document.querySelector('input[data-testid="stTextInput-{target_input_key}"]');
14
+ const statusDiv = document.getElementById('status-{target_input_key}');
15
+ const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
16
+ recognition.lang = 'en-US';
17
+
18
+ recognition.onstart = () => {{
19
+ statusDiv.innerHTML = '<div style="color: red; margin-left: 5px; animation: blink 1s infinite;">🎤 Listening...</div>';
20
+ }};
21
+
22
+ recognition.onresult = (event) => {{
23
+ const transcript = event.results[0][0].transcript;
24
+ {"if(targetElem) targetElem.value = transcript;" if not is_select else
25
+ "const selectElem = document.querySelector('select[data-testid=\"stSelectbox-{target_input_key}\"]');" +
26
+ "if(selectElem) { const option = Array.from(selectElem.options).find(opt => opt.text.toLowerCase().includes(transcript.toLowerCase()));" +
27
+ "if(option) selectElem.value = option.value; }"}
28
+ }};
29
+
30
+ recognition.onerror = () => {{
31
+ statusDiv.innerHTML = '<div style="color: red; margin-left: 5px;">❌ Error</div>';
32
+ }};
33
+
34
+ recognition.start();
35
+ }}
36
+ </script>
37
+
38
+ <style>
39
+ @keyframes blink {{
40
+ 0% {{ opacity: 1; }}
41
+ 50% {{ opacity: 0; }}
42
+ 100% {{ opacity: 1; }}
43
+ }}
44
+ .mic-button {{
45
+ background: #6C63FF !important;
46
+ border-radius: 50%;
47
+ width: 36px;
48
+ height: 36px;
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ cursor: pointer;
53
+ margin-left: 8px;
54
+ }}
55
+ .input-row {{
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 8px;
59
+ }}
60
+ </style>
61
+
62
+ <div class="input-row">
63
+ <div id="status-{target_input_key}" style="display: flex; align-items: center;"></div>
64
+ <button class="mic-button" onclick="startSpeechRecognition{target_input_key}()">
65
+ <svg style="width:20px;height:20px;fill:white;" viewBox="0 0 24 24">
66
+ <path d="M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z"/>
67
+ </svg>
68
+ </button>
69
+ </div>
70
+ """)
71
+
72
  # Import transformers and cache the help agent for performance
73
  @st.cache_resource
74
  def get_help_agent():
 
82
  <style>
83
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
84
  @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css');
 
85
  * {
86
  font-family: 'Inter', sans-serif;
87
  }
 
88
  body {
89
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
90
  }
 
91
  .title {
92
  font-size: 2.8rem !important;
93
  font-weight: 800 !important;
 
98
  margin: 1rem 0;
99
  letter-spacing: -1px;
100
  }
 
101
  .subtitle {
102
  font-size: 1.1rem !important;
103
  text-align: center;
 
105
  margin-bottom: 2.5rem;
106
  animation: fadeInSlide 1s ease;
107
  }
 
108
  .question-box {
109
  background: white;
110
  border-radius: 20px;
 
116
  transition: transform 0.2s ease;
117
  color: black;
118
  }
 
119
  .question-box:hover {
120
  transform: translateY(-3px);
121
  }
 
122
  .question-box::before {
123
  content: "🕹️";
124
  position: absolute;
 
130
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
131
  font-size: 1.2rem;
132
  }
 
133
  .input-box {
134
  background: white;
135
  border-radius: 12px;
 
137
  margin: 1rem 0;
138
  box-shadow: 0 4px 6px rgba(0,0,0,0.05);
139
  }
 
140
  .stTextInput input {
141
  border: 2px solid #e2e8f0 !important;
142
  border-radius: 10px !important;
143
  padding: 12px 16px !important;
144
  transition: all 0.3s ease !important;
145
  }
 
146
  .stTextInput input:focus {
147
  border-color: #6C63FF !important;
148
  box-shadow: 0 0 0 3px rgba(108, 99, 255, 0.2) !important;
149
  }
 
150
  button {
151
  background: linear-gradient(45deg, #6C63FF, #3B82F6) !important;
152
  color: white !important;
 
156
  font-weight: 600 !important;
157
  transition: all 0.3s ease !important;
158
  }
 
159
  button:hover {
160
  transform: translateY(-2px);
161
  box-shadow: 0 5px 15px rgba(108, 99, 255, 0.3) !important;
162
  }
 
163
  .final-reveal {
164
  animation: fadeInUp 1s ease;
165
  font-size: 2.8rem;
 
170
  margin: 2rem 0;
171
  font-weight: 800;
172
  }
 
173
  .help-chat {
174
  background: rgba(255,255,255,0.9);
175
  backdrop-filter: blur(10px);
 
178
  margin: 1rem 0;
179
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
180
  }
 
181
  @keyframes fadeInSlide {
182
  0% { opacity: 0; transform: translateY(20px); }
183
  100% { opacity: 1; transform: translateY(0); }
184
  }
 
185
  @keyframes fadeInUp {
186
  0% { opacity: 0; transform: translateY(30px); }
187
  100% { opacity: 1; transform: translateY(0); }
188
  }
 
189
  .progress-bar {
190
  height: 6px;
191
  background: #e2e8f0;
 
193
  margin: 1.5rem 0;
194
  overflow: hidden;
195
  }
 
196
  .progress-fill {
197
  height: 100%;
198
  background: linear-gradient(90deg, #6C63FF, #3B82F6);
199
  transition: width 0.5s ease;
200
  }
 
201
  .question-count {
202
  color: #6C63FF;
203
  font-weight: 600;
 
218
  origin: { y: 0.7 },
219
  zIndex: 1050
220
  };
 
221
  function fire(particleRatio, opts) {
222
  confetti(Object.assign({}, defaults, opts, {
223
  particleCount: Math.floor(count * particleRatio)
224
  }));
225
  }
 
226
  fire(0.25, { spread: 26, startVelocity: 55 });
227
  fire(0.2, { spread: 60 });
228
  fire(0.35, { spread: 100, decay: 0.91, scalar: 0.8 });
 
320
  except Exception as e:
321
  return f"Error in help agent: {str(e)}"
322
 
 
323
  # Main game logic with enhanced UI
324
  def main():
325
  inject_custom_css()
 
365
  """, unsafe_allow_html=True)
366
 
367
  with st.form("start_form"):
368
+ col1, col2 = st.columns([4, 1])
369
+ with col1:
370
+ category_input = st.text_input("Enter category (person/place/object):", key="category_input").strip().lower()
371
+ with col2:
372
+ st.markdown("<div style='height: 30px;'></div>")
373
+ add_mic_button("category_input")
374
+
375
  if st.form_submit_button("Start Game"):
376
  if not category_input:
377
  st.error("Please enter a category!")
 
424
  st.experimental_rerun()
425
 
426
  with st.form("answer_form"):
427
+ col1, col2 = st.columns([4, 1])
428
+ with col1:
429
+ answer_input = st.text_input("Your answer (yes/no/both):",
430
+ key=f"answer_{st.session_state.current_q}").strip().lower()
431
+ with col2:
432
+ st.markdown("<div style='height: 30px;'></div>")
433
+ add_mic_button(f"answer_{st.session_state.current_q}")
434
+
435
  if st.form_submit_button("Submit"):
436
  if answer_input not in ["yes", "no", "both"]:
437
  st.error("Please answer with 'yes', 'no', or 'both'!")
 
496
  ''', unsafe_allow_html=True)
497
 
498
  with st.form("confirm_form"):
499
+ col1, col2 = st.columns([4, 1])
500
+ with col1:
501
+ confirm_input = st.text_input("Type your answer (yes/no/both):", key="confirm_input").strip().lower()
502
+ with col2:
503
+ st.markdown("<div style='height: 30px;'></div>")
504
+ add_mic_button("confirm_input")
505
+
506
  if st.form_submit_button("Submit"):
507
  if confirm_input not in ["yes", "no", "both"]:
508
  st.error("Please answer with 'yes', 'no', or 'both'!")