zach commited on
Commit
706bed4
·
1 Parent(s): 6bb0509

Fix styling for displaying results

Browse files
Files changed (1) hide show
  1. src/app.py +80 -21
src/app.py CHANGED
@@ -187,7 +187,6 @@ class App:
187
  logger.error(f"Unexpected error during TTS generation: {e}")
188
  raise gr.Error("An unexpected error occurred. Please try again later.")
189
 
190
-
191
  async def _vote(
192
  self,
193
  vote_submitted: bool,
@@ -196,24 +195,29 @@ class App:
196
  text_modified: bool,
197
  character_description: str,
198
  text: str,
199
- ) -> Tuple[bool, dict, dict, dict]:
200
  """
201
- Handles user voting.
202
 
203
  Args:
204
  vote_submitted (bool): True if a vote was already submitted.
205
  option_map (OptionMap): A dictionary mapping option labels to their details.
206
  clicked_option_button (str): The button that was clicked.
 
 
 
207
 
208
  Returns:
209
  A tuple of:
210
  - A boolean indicating if the vote was accepted.
211
- - A dict update for the selected vote button (showing provider and trophy emoji).
212
- - A dict update for the unselected vote button (showing provider).
213
- - A dict update for enabling vote interactions.
 
 
214
  """
215
  if not option_map or vote_submitted:
216
- return gr.skip(), gr.skip(), gr.skip(), gr.skip()
217
 
218
  selected_option, other_option = determine_selected_option(clicked_option_button)
219
  selected_provider = option_map[selected_option]["provider"]
@@ -238,20 +242,22 @@ class App:
238
 
239
  return (
240
  True,
 
 
241
  (
242
- gr.update(value=selected_label, variant="primary")
243
  if selected_option == constants.OPTION_A_KEY
244
- else gr.update(value=other_label, variant="secondary")
245
  ),
246
  (
247
- gr.update(value=other_label, variant="secondary")
248
  if selected_option == constants.OPTION_A_KEY
249
- else gr.update(value=selected_label, variant="primary")
250
  ),
251
  gr.update(interactive=True),
252
  )
253
 
254
- def _reset_ui(self) -> Tuple[dict, dict, dict, dict, OptionMap, bool]:
255
  """
256
  Resets UI state before generating new text.
257
 
@@ -259,8 +265,10 @@ class App:
259
  A tuple of updates for:
260
  - option_a_audio_player (clear audio)
261
  - option_b_audio_player (clear audio)
262
- - vote_button_a (disable and reset button text)
263
- - vote_button_b (disable and reset button text)
 
 
264
  - option_map_state (reset option map state)
265
  - vote_submitted_state (reset submitted vote state)
266
  """
@@ -269,12 +277,14 @@ class App:
269
  "option_b": {"provider": constants.HUME_AI, "generation_id": None, "audio_file_path": ""},
270
  }
271
  return (
272
- gr.update(value=None),
273
- gr.update(value=None, autoplay=False),
274
- gr.update(value=constants.SELECT_OPTION_A, variant="secondary", interactive=False),
275
- gr.update(value=constants.SELECT_OPTION_B, variant="secondary", interactive=False),
 
 
276
  default_option_map, # Reset option_map_state as a default OptionMap
277
- False,
278
  )
279
 
280
  def _build_input_section(self) -> Tuple[gr.Dropdown, gr.Textbox, gr.Button]:
@@ -304,9 +314,18 @@ class App:
304
  generate_text_button,
305
  )
306
 
307
- def _build_output_section(self) -> Tuple[gr.Textbox, gr.Button, gr.Audio, gr.Audio, gr.Button, gr.Button]:
 
 
 
 
 
 
 
 
 
308
  """
309
- Builds the output section including text input, audio players, and vote buttons.
310
  """
311
  with gr.Group():
312
  text_input = gr.Textbox(
@@ -333,6 +352,14 @@ class App:
333
  constants.SELECT_OPTION_A,
334
  interactive=False,
335
  )
 
 
 
 
 
 
 
 
336
  with gr.Column():
337
  with gr.Group():
338
  option_b_audio_player = gr.Audio(
@@ -344,6 +371,14 @@ class App:
344
  constants.SELECT_OPTION_B,
345
  interactive=False,
346
  )
 
 
 
 
 
 
 
 
347
 
348
  return (
349
  text_input,
@@ -352,6 +387,8 @@ class App:
352
  option_b_audio_player,
353
  vote_button_a,
354
  vote_button_b,
 
 
355
  )
356
 
357
  def build_gradio_interface(self) -> gr.Blocks:
@@ -361,10 +398,24 @@ class App:
361
  Returns:
362
  gr.Blocks: The fully constructed Gradio UI layout.
363
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  with gr.Blocks(
365
  title="Expressive TTS Arena",
366
  fill_width=True,
367
  css_paths="src/assets/styles.css",
 
368
  ) as demo:
369
  # --- UI components ---
370
  gr.Markdown("# Expressive TTS Arena")
@@ -409,6 +460,8 @@ class App:
409
  option_b_audio_player,
410
  vote_button_a,
411
  vote_button_b,
 
 
412
  ) = self._build_output_section()
413
 
414
  # --- UI state components ---
@@ -472,6 +525,8 @@ class App:
472
  option_b_audio_player,
473
  vote_button_a,
474
  vote_button_b,
 
 
475
  option_map_state,
476
  vote_submitted_state,
477
  ],
@@ -518,6 +573,8 @@ class App:
518
  vote_submitted_state,
519
  vote_button_a,
520
  vote_button_b,
 
 
521
  synthesize_speech_button,
522
  ],
523
  )
@@ -543,6 +600,8 @@ class App:
543
  vote_submitted_state,
544
  vote_button_a,
545
  vote_button_b,
 
 
546
  synthesize_speech_button,
547
  ],
548
  )
 
187
  logger.error(f"Unexpected error during TTS generation: {e}")
188
  raise gr.Error("An unexpected error occurred. Please try again later.")
189
 
 
190
  async def _vote(
191
  self,
192
  vote_submitted: bool,
 
195
  text_modified: bool,
196
  character_description: str,
197
  text: str,
198
+ ) -> Tuple[bool, dict, dict, dict, dict, dict]:
199
  """
200
+ Handles user voting and updates the UI to display vote results.
201
 
202
  Args:
203
  vote_submitted (bool): True if a vote was already submitted.
204
  option_map (OptionMap): A dictionary mapping option labels to their details.
205
  clicked_option_button (str): The button that was clicked.
206
+ text_modified (bool): Whether the text was modified by the user.
207
+ character_description (str): The character description.
208
+ text (str): The text used for synthesis.
209
 
210
  Returns:
211
  A tuple of:
212
  - A boolean indicating if the vote was accepted.
213
+ - A dict update for hiding vote button A.
214
+ - A dict update for hiding vote button B.
215
+ - A dict update for showing vote result A textbox.
216
+ - A dict update for showing vote result B textbox.
217
+ - A dict update for enabling the synthesize speech button.
218
  """
219
  if not option_map or vote_submitted:
220
+ return gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip()
221
 
222
  selected_option, other_option = determine_selected_option(clicked_option_button)
223
  selected_provider = option_map[selected_option]["provider"]
 
242
 
243
  return (
244
  True,
245
+ gr.update(visible=False),
246
+ gr.update(visible=False),
247
  (
248
+ gr.update(value=selected_label, visible=True, elem_classes="winner")
249
  if selected_option == constants.OPTION_A_KEY
250
+ else gr.update(value=other_label, visible=True)
251
  ),
252
  (
253
+ gr.update(value=other_label, visible=True)
254
  if selected_option == constants.OPTION_A_KEY
255
+ else gr.update(value=selected_label, visible=True, elem_classes="winner")
256
  ),
257
  gr.update(interactive=True),
258
  )
259
 
260
+ def _reset_ui(self) -> Tuple[dict, dict, dict, dict, dict, dict, OptionMap, bool]:
261
  """
262
  Resets UI state before generating new text.
263
 
 
265
  A tuple of updates for:
266
  - option_a_audio_player (clear audio)
267
  - option_b_audio_player (clear audio)
268
+ - vote_button_a (show)
269
+ - vote_button_b (show)
270
+ - vote_result_a (hide)
271
+ - vote_result_b (hide)
272
  - option_map_state (reset option map state)
273
  - vote_submitted_state (reset submitted vote state)
274
  """
 
277
  "option_b": {"provider": constants.HUME_AI, "generation_id": None, "audio_file_path": ""},
278
  }
279
  return (
280
+ gr.update(value=None), # clear audio player A
281
+ gr.update(value=None, autoplay=False), # clear audio player B
282
+ gr.update(visible=True, interactive=False), # show vote button A
283
+ gr.update(visible=True, interactive=False), # show vote button B
284
+ gr.update(visible=False, elem_classes=[]), # hide vote result A
285
+ gr.update(visible=False, elem_classes=[]), # hide vote result B
286
  default_option_map, # Reset option_map_state as a default OptionMap
287
+ False, # Reset vote_submitted_state
288
  )
289
 
290
  def _build_input_section(self) -> Tuple[gr.Dropdown, gr.Textbox, gr.Button]:
 
314
  generate_text_button,
315
  )
316
 
317
+ def _build_output_section(self) -> Tuple[
318
+ gr.Textbox,
319
+ gr.Button,
320
+ gr.Audio,
321
+ gr.Audio,
322
+ gr.Button,
323
+ gr.Button,
324
+ gr.Textbox,
325
+ gr.Textbox,
326
+ ]:
327
  """
328
+ Builds the output section including text input, audio players, vote buttons, and vote result displays.
329
  """
330
  with gr.Group():
331
  text_input = gr.Textbox(
 
352
  constants.SELECT_OPTION_A,
353
  interactive=False,
354
  )
355
+ vote_result_a = gr.Textbox(
356
+ label="",
357
+ interactive=False,
358
+ visible=False,
359
+ elem_id="vote-result-a",
360
+ text_align="center",
361
+ container=False,
362
+ )
363
  with gr.Column():
364
  with gr.Group():
365
  option_b_audio_player = gr.Audio(
 
371
  constants.SELECT_OPTION_B,
372
  interactive=False,
373
  )
374
+ vote_result_b = gr.Textbox(
375
+ label="",
376
+ interactive=False,
377
+ visible=False,
378
+ elem_id="vote-result-b",
379
+ text_align="center",
380
+ container=False,
381
+ )
382
 
383
  return (
384
  text_input,
 
387
  option_b_audio_player,
388
  vote_button_a,
389
  vote_button_b,
390
+ vote_result_a,
391
+ vote_result_b,
392
  )
393
 
394
  def build_gradio_interface(self) -> gr.Blocks:
 
398
  Returns:
399
  gr.Blocks: The fully constructed Gradio UI layout.
400
  """
401
+ custom_css = """
402
+ #vote-result-a textarea,
403
+ #vote-result-b textarea {
404
+ font-size: 16px !important;
405
+ font-weight: bold !important;
406
+ }
407
+
408
+ #vote-result-a.winner textarea,
409
+ #vote-result-b.winner textarea {
410
+ background: #EA580C;
411
+ }
412
+ """
413
+
414
  with gr.Blocks(
415
  title="Expressive TTS Arena",
416
  fill_width=True,
417
  css_paths="src/assets/styles.css",
418
+ css=custom_css,
419
  ) as demo:
420
  # --- UI components ---
421
  gr.Markdown("# Expressive TTS Arena")
 
460
  option_b_audio_player,
461
  vote_button_a,
462
  vote_button_b,
463
+ vote_result_a,
464
+ vote_result_b,
465
  ) = self._build_output_section()
466
 
467
  # --- UI state components ---
 
525
  option_b_audio_player,
526
  vote_button_a,
527
  vote_button_b,
528
+ vote_result_a,
529
+ vote_result_b,
530
  option_map_state,
531
  vote_submitted_state,
532
  ],
 
573
  vote_submitted_state,
574
  vote_button_a,
575
  vote_button_b,
576
+ vote_result_a,
577
+ vote_result_b,
578
  synthesize_speech_button,
579
  ],
580
  )
 
600
  vote_submitted_state,
601
  vote_button_a,
602
  vote_button_b,
603
+ vote_result_a,
604
+ vote_result_b,
605
  synthesize_speech_button,
606
  ],
607
  )