Kesheratmex commited on
Commit
c3348cf
·
1 Parent(s): b88673d

**Subject**

Browse files

Improve login UI contrast and unify media processing logic

**Body**
Add new CSS styles for the login section to enhance contrast, readability, and overall visual hierarchy.
Refactor the media handling into a single `process_media_unified` function that supports both video and image uploads, includes error handling for missing files, and shows a loading indicator.
Simplify the button click chain by removing separate `process_video` and `process_image` functions, leading to cleaner code and better user feedback.

Files changed (1) hide show
  1. app.py +113 -29
app.py CHANGED
@@ -1233,6 +1233,46 @@ with gr.Blocks(
1233
  .toast.warning { background: #fff3cd !important; color: #856404 !important; border-color: #ffeaa7 !important; }
1234
  .toast.info { background: #d1ecf1 !important; color: #0c5460 !important; border-color: #bee5eb !important; }
1235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1236
  /* ===== OVERRIDE FINAL ===== */
1237
  /* Asegurar que nada sobrescriba nuestros estilos */
1238
  [data-testid*="slider"] {
@@ -1707,41 +1747,85 @@ with gr.Blocks(
1707
  gr.Markdown(visible=False)
1708
  )
1709
 
1710
- # Wire up the detection events with proper output visibility and loading animation
1711
- def process_video():
1712
- return show_loading()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1713
 
1714
- def process_image():
1715
- return show_loading()
 
1716
 
1717
- # Video processing chain
1718
- btn_detect.click(
1719
- fn=lambda: show_loading(),
1720
- outputs=loading_status
1721
- ).then(
1722
- fn=infer_media_with_loading,
1723
- inputs=video_input,
1724
- outputs=json_video,
1725
- api_name="infer_media"
1726
- ).then(
1727
- fn=_update_video_output,
1728
- inputs=json_video,
1729
- outputs=[loading_status, output_video, output_image, analysis_text]
1730
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1731
 
1732
- # Image processing chain
1733
  btn_detect.click(
1734
- fn=lambda: show_loading(),
1735
  outputs=loading_status
1736
  ).then(
1737
- fn=infer_media_with_loading,
1738
- inputs=image_input,
1739
- outputs=json_image,
1740
- api_name="infer_media_1"
1741
- ).then(
1742
- fn=_update_image_output,
1743
- inputs=json_image,
1744
- outputs=[loading_status, output_video, output_image, analysis_text]
1745
  )
1746
 
1747
  # Wire the gate
 
1233
  .toast.warning { background: #fff3cd !important; color: #856404 !important; border-color: #ffeaa7 !important; }
1234
  .toast.info { background: #d1ecf1 !important; color: #0c5460 !important; border-color: #bee5eb !important; }
1235
 
1236
+ /* ===== SECCIÓN DE LOGIN - CONTRASTE MEJORADO ===== */
1237
+ .section-container {
1238
+ background: #ffffff !important;
1239
+ border: 1px solid #dee2e6 !important;
1240
+ border-radius: 12px !important;
1241
+ padding: 25px !important;
1242
+ margin: 20px 0 !important;
1243
+ box-shadow: 0 4px 15px rgba(0,0,0,0.08) !important;
1244
+ }
1245
+
1246
+ .section-container h2 {
1247
+ color: #212529 !important;
1248
+ font-weight: 700 !important;
1249
+ font-size: 1.5rem !important;
1250
+ margin-bottom: 20px !important;
1251
+ }
1252
+
1253
+ .section-container p {
1254
+ color: #212529 !important;
1255
+ font-weight: 500 !important;
1256
+ font-size: 16px !important;
1257
+ margin-bottom: 20px !important;
1258
+ line-height: 1.5 !important;
1259
+ }
1260
+
1261
+ /* Labels y texto de ayuda en inputs */
1262
+ .gr-textbox label, .gr-file label, .gr-dropdown label {
1263
+ color: #212529 !important;
1264
+ font-weight: 600 !important;
1265
+ font-size: 1rem !important;
1266
+ margin-bottom: 8px !important;
1267
+ }
1268
+
1269
+ .gr-textbox .gr-info, .gr-file .gr-info, .gr-dropdown .gr-info {
1270
+ color: #495057 !important;
1271
+ font-weight: 500 !important;
1272
+ font-size: 0.9rem !important;
1273
+ margin-top: 5px !important;
1274
+ }
1275
+
1276
  /* ===== OVERRIDE FINAL ===== */
1277
  /* Asegurar que nada sobrescriba nuestros estilos */
1278
  [data-testid*="slider"] {
 
1747
  gr.Markdown(visible=False)
1748
  )
1749
 
1750
+ # Función unificada para manejar tanto video como imagen
1751
+ def process_media_unified(video_file, image_file):
1752
+ """Procesa video o imagen según cuál esté disponible"""
1753
+ # Determinar qué tipo de archivo tenemos
1754
+ media_path = None
1755
+ if video_file is not None:
1756
+ media_path = video_file
1757
+ elif image_file is not None:
1758
+ media_path = image_file if isinstance(image_file, str) else getattr(image_file, "name", None)
1759
+
1760
+ if not media_path:
1761
+ return (
1762
+ gr.HTML(value="<div style='color: red; padding: 20px; text-align: center;'>ERROR: No se ha seleccionado ningún archivo para analizar</div>", visible=True),
1763
+ gr.Video(visible=False),
1764
+ gr.Image(visible=False),
1765
+ gr.Markdown(visible=False)
1766
+ )
1767
 
1768
+ # Mostrar loading y procesar
1769
+ try:
1770
+ result = infer_media_with_loading(media_path)
1771
 
1772
+ if result and result.get("video"):
1773
+ # Es un video - generar análisis
1774
+ classes = result.get("classes", {})
1775
+ if classes:
1776
+ detections_summary = "Detecciones automáticas: " + ", ".join([f"{k}: {v}" for k, v in classes.items()])
1777
+ else:
1778
+ detections_summary = "No se detectaron defectos automáticamente"
1779
+
1780
+ analysis = analyze_image_with_ai(media_path, detections_summary)
1781
+
1782
+ return (
1783
+ gr.HTML(visible=False), # Hide loading
1784
+ gr.Video(value=result["video"], visible=True),
1785
+ gr.Image(visible=False),
1786
+ gr.Markdown(value=analysis, visible=True)
1787
+ )
1788
+ elif result and result.get("path"):
1789
+ # Es una imagen - generar análisis
1790
+ classes = result.get("classes", {})
1791
+ if classes:
1792
+ detections_summary = "Detecciones automáticas: " + ", ".join([f"{k}: {v}" for k, v in classes.items()])
1793
+ else:
1794
+ detections_summary = "No se detectaron defectos automáticamente"
1795
+
1796
+ analysis = analyze_image_with_ai(result["path"], detections_summary)
1797
+
1798
+ return (
1799
+ gr.HTML(visible=False), # Hide loading
1800
+ gr.Video(visible=False),
1801
+ gr.Image(value=result["path"], visible=True),
1802
+ gr.Markdown(value=analysis, visible=True)
1803
+ )
1804
+ else:
1805
+ # Error en el procesamiento
1806
+ return (
1807
+ gr.HTML(value="<div style='color: red; padding: 20px; text-align: center;'>ERROR: No se pudo procesar el archivo</div>", visible=True),
1808
+ gr.Video(visible=False),
1809
+ gr.Image(visible=False),
1810
+ gr.Markdown(visible=False)
1811
+ )
1812
+ except Exception as e:
1813
+ return (
1814
+ gr.HTML(value=f"<div style='color: red; padding: 20px; text-align: center;'>ERROR: {str(e)}</div>", visible=True),
1815
+ gr.Video(visible=False),
1816
+ gr.Image(visible=False),
1817
+ gr.Markdown(visible=False)
1818
+ )
1819
 
1820
+ # Evento unificado del botón
1821
  btn_detect.click(
1822
+ fn=show_loading,
1823
  outputs=loading_status
1824
  ).then(
1825
+ fn=process_media_unified,
1826
+ inputs=[video_input, image_input],
1827
+ outputs=[loading_status, output_video, output_image, analysis_text],
1828
+ api_name="analyze_media"
 
 
 
 
1829
  )
1830
 
1831
  # Wire the gate