Roudrigus commited on
Commit
293de9b
·
verified ·
1 Parent(s): fc81bc5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -11
app.py CHANGED
@@ -149,20 +149,26 @@ def _set_query_params(new_params: dict):
149
  except Exception:
150
  pass
151
 
 
152
  def _check_rerun_qs(pagina_atual: str = ""):
153
  """
154
  Se a URL contiver rr=1 (ou true), força um rerun e limpa o parâmetro para evitar loop.
155
  ✅ Não dispara quando estiver na página 'resposta' (Inbox Admin).
156
- ✅ Consome apenas uma vez por sessão.
157
  ✅ (PATCH) Também não dispara quando estiver em 'outlook_relatorio' para não interromper leitura COM.
158
  ✅ (PATCH) Não dispara quando estiver em 'formulario'.
 
159
  """
160
  try:
161
  if st.session_state.get("__qs_rr_consumed__", False):
162
  return
163
- # 🔒 Evita rr=1 em módulos sensíveis a rerun/refresh
 
 
 
 
 
164
  if pagina_atual in ("resposta", "outlook_relatorio", "formulario"):
165
- return # não aplicar rr=1 dentro destes módulos (evita 'piscar' e cancelamentos)
166
 
167
  params = _get_query_params()
168
  rr_raw = params.get("rr", ["0"])
@@ -415,6 +421,8 @@ def _render_aviso_global_topbar():
415
  font_size = 14
416
 
417
  altura = 52 # px
 
 
418
 
419
  st.markdown(
420
  f"""
@@ -428,9 +436,10 @@ header[data-testid="stHeader"],
428
  .stApp [class*="stDialog"] {{
429
  z-index: 1 !important;
430
  }}
431
- /* Reserva espaço para a barra */
 
432
  [data-testid="stAppViewContainer"] {{
433
- padding-top: {altura + 8}px !important;
434
  }}
435
 
436
  .ag-topbar-wrap {{
@@ -445,7 +454,14 @@ header[data-testid="stHeader"],
445
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
446
  border-radius: 0 0 10px 10px;
447
  pointer-events: none;
 
 
 
 
 
 
448
  }}
 
449
  .ag-topbar-inner {{
450
  display: flex;
451
  align-items: center;
@@ -456,16 +472,29 @@ header[data-testid="stHeader"],
456
  font-size: {font_size}px;
457
  letter-spacing: .2px;
458
  white-space: nowrap;
 
 
 
 
 
459
  }}
 
460
  .ag-topbar-marquee > span {{
461
  display: inline-block;
462
  padding-left: 100%;
463
  animation: ag-marquee {velocidade}s linear infinite;
 
 
 
 
 
464
  }}
 
465
  @keyframes ag-marquee {{
466
  0% {{ transform: translateX(0); }}
467
  100% {{ transform: translateX(-100%); }}
468
  }}
 
469
  /* Acessibilidade: reduz movimento */
470
  @media (prefers-reduced-motion: reduce) {{
471
  .ag-topbar-marquee > span {{
@@ -473,18 +502,19 @@ header[data-testid="stHeader"],
473
  padding-left: 0;
474
  }}
475
  }}
 
476
  @media (max-width: 500px) {{
477
  .ag-topbar-inner {{
478
  font-size: {max(10, font_size-3)}px;
479
  padding: 0 8px;
480
  height: 44px;
481
  }}
 
482
  [data-testid="stAppViewContainer"] {{
483
- padding-top: 52px !important;
484
  }}
485
  }}
486
  </style>
487
-
488
  <div class="ag-topbar-wrap">
489
  <div class="ag-topbar-inner {'ag-topbar-marquee' if efeito=='marquee' else ''}">
490
  <span>{aviso.mensagem}</span>
@@ -619,6 +649,27 @@ def _render_auth_diag_panel():
619
  except Exception as e:
620
  st.sidebar.error(f"Falha ao importar login.py: {e}")
621
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  # ===============================
623
  # MAIN
624
  # ===============================
@@ -640,7 +691,8 @@ def main():
640
  # LOGIN
641
  if not st.session_state.logado:
642
  st.session_state.quiz_verificado = False
643
- exibir_logo(top=True, sidebar=False)
 
644
  login()
645
 
646
  # ⚠️ Opcional: dica breve quando nenhum caminho de auth está definido
@@ -859,7 +911,8 @@ def main():
859
  # QUIZ
860
  if not st.session_state.quiz_verificado:
861
  if not quiz_respondido_hoje(usuario):
862
- exibir_logo(top=True, sidebar=False)
 
863
  quiz.main()
864
  return
865
  else:
@@ -867,7 +920,8 @@ def main():
867
  st.rerun()
868
 
869
  # SISTEMA LIBERADO
870
- exibir_logo(top=True, sidebar=True)
 
871
  _render_aviso_global_topbar()
872
  _show_birthday_banner_if_needed()
873
 
@@ -1106,8 +1160,12 @@ def main():
1106
  is_outlook_rel = (pagina_id == "outlook_relatorio")
1107
  is_formulario = (pagina_id == "formulario")
1108
  is_recebimento = (pagina_id == "recebimento")
 
 
 
 
1109
  interval_sec = int(st.session_state.get("__auto_refresh_interval_sec__", 60))
1110
- if (interval_sec > 0) and not (is_inbox_admin or is_outlook_rel or is_formulario or is_recebimento):
1111
  st_autorefresh(interval=interval_sec * 1000, key=f"sidebar_autorefresh_{interval_sec}s")
1112
  except Exception:
1113
  pass
 
149
  except Exception:
150
  pass
151
 
152
+ # 🔒 ANTI-TREMOR PATCH: não consumir rr=1 quando login/quiz ainda não concluídos
153
  def _check_rerun_qs(pagina_atual: str = ""):
154
  """
155
  Se a URL contiver rr=1 (ou true), força um rerun e limpa o parâmetro para evitar loop.
156
  ✅ Não dispara quando estiver na página 'resposta' (Inbox Admin).
 
157
  ✅ (PATCH) Também não dispara quando estiver em 'outlook_relatorio' para não interromper leitura COM.
158
  ✅ (PATCH) Não dispara quando estiver em 'formulario'.
159
+ ✅ (ANTI-TREMOR) Não dispara enquanto login/quiz não concluídos (para não mexer na logo).
160
  """
161
  try:
162
  if st.session_state.get("__qs_rr_consumed__", False):
163
  return
164
+
165
+ # Evita rr=1 quando a tela está em login/quiz (logo mais evidente)
166
+ if (not st.session_state.get("logado")) or (not st.session_state.get("quiz_verificado")):
167
+ return
168
+
169
+ # Evita rr=1 em módulos sensíveis a rerun/refresh
170
  if pagina_atual in ("resposta", "outlook_relatorio", "formulario"):
171
+ return # evita 'piscar' e cancelamentos
172
 
173
  params = _get_query_params()
174
  rr_raw = params.get("rr", ["0"])
 
421
  font_size = 14
422
 
423
  altura = 52 # px
424
+ # 🔒 ANTI-TREMOR PATCH: padding-top constante e levemente maior que a topbar
425
+ padding_top = max(60, altura + 8)
426
 
427
  st.markdown(
428
  f"""
 
436
  .stApp [class*="stDialog"] {{
437
  z-index: 1 !important;
438
  }}
439
+
440
+ /* 🔒 ANTI-TREMOR: reserva fixa do topo para a barra */
441
  [data-testid="stAppViewContainer"] {{
442
+ padding-top: {padding_top}px !important;
443
  }}
444
 
445
  .ag-topbar-wrap {{
 
454
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
455
  border-radius: 0 0 10px 10px;
456
  pointer-events: none;
457
+
458
+ /* 🔒 ANTI-TREMOR: compositor-only + isolamento */
459
+ will-change: transform, opacity;
460
+ contain: layout paint size;
461
+ backface-visibility: hidden;
462
+ transform: translateZ(0);
463
  }}
464
+
465
  .ag-topbar-inner {{
466
  display: flex;
467
  align-items: center;
 
472
  font-size: {font_size}px;
473
  letter-spacing: .2px;
474
  white-space: nowrap;
475
+
476
+ /* 🔒 ANTI-TREMOR */
477
+ will-change: transform, opacity;
478
+ backface-visibility: hidden;
479
+ transform: translateZ(0);
480
  }}
481
+
482
  .ag-topbar-marquee > span {{
483
  display: inline-block;
484
  padding-left: 100%;
485
  animation: ag-marquee {velocidade}s linear infinite;
486
+
487
+ /* 🔒 ANTI-TREMOR */
488
+ will-change: transform;
489
+ backface-visibility: hidden;
490
+ transform: translateZ(0);
491
  }}
492
+
493
  @keyframes ag-marquee {{
494
  0% {{ transform: translateX(0); }}
495
  100% {{ transform: translateX(-100%); }}
496
  }}
497
+
498
  /* Acessibilidade: reduz movimento */
499
  @media (prefers-reduced-motion: reduce) {{
500
  .ag-topbar-marquee > span {{
 
502
  padding-left: 0;
503
  }}
504
  }}
505
+
506
  @media (max-width: 500px) {{
507
  .ag-topbar-inner {{
508
  font-size: {max(10, font_size-3)}px;
509
  padding: 0 8px;
510
  height: 44px;
511
  }}
512
+ /* 🔒 ANTI-TREMOR: manter reserva estável no mobile também */
513
  [data-testid="stAppViewContainer"] {{
514
+ padding-top: {padding_top}px !important;
515
  }}
516
  }}
517
  </style>
 
518
  <div class="ag-topbar-wrap">
519
  <div class="ag-topbar-inner {'ag-topbar-marquee' if efeito=='marquee' else ''}">
520
  <span>{aviso.mensagem}</span>
 
649
  except Exception as e:
650
  st.sidebar.error(f"Falha ao importar login.py: {e}")
651
 
652
+ # ===============================
653
+ # 🔒 ANTI-TREMOR PATCH: wrapper idempotente para a LOGO
654
+ # ===============================
655
+ def exibir_logo_once(top: bool = False, sidebar: bool = False):
656
+ """
657
+ Garante que a logo só seja inserida uma vez por posição (top e/ou sidebar) por sessão.
658
+ Se for chamada novamente, não reinjeta o HTML nem causa reflows.
659
+ """
660
+ state = st.session_state.setdefault("__logo_once__", {"top": False, "sidebar": False})
661
+ need_top = bool(top and not state["top"])
662
+ need_sidebar = bool(sidebar and not state["sidebar"])
663
+
664
+ if need_top or need_sidebar:
665
+ try:
666
+ exibir_logo(top=need_top, sidebar=need_sidebar)
667
+ finally:
668
+ if need_top:
669
+ state["top"] = True
670
+ if need_sidebar:
671
+ state["sidebar"] = True
672
+
673
  # ===============================
674
  # MAIN
675
  # ===============================
 
691
  # LOGIN
692
  if not st.session_state.logado:
693
  st.session_state.quiz_verificado = False
694
+ # 🔒 ANTI-TREMOR: renderiza logo top apenas 1x
695
+ exibir_logo_once(top=True, sidebar=False)
696
  login()
697
 
698
  # ⚠️ Opcional: dica breve quando nenhum caminho de auth está definido
 
911
  # QUIZ
912
  if not st.session_state.quiz_verificado:
913
  if not quiz_respondido_hoje(usuario):
914
+ # 🔒 ANTI-TREMOR: render 1x
915
+ exibir_logo_once(top=True, sidebar=False)
916
  quiz.main()
917
  return
918
  else:
 
920
  st.rerun()
921
 
922
  # SISTEMA LIBERADO
923
+ # 🔒 ANTI-TREMOR: render 1x (topo + sidebar)
924
+ exibir_logo_once(top=True, sidebar=True)
925
  _render_aviso_global_topbar()
926
  _show_birthday_banner_if_needed()
927
 
 
1160
  is_outlook_rel = (pagina_id == "outlook_relatorio")
1161
  is_formulario = (pagina_id == "formulario")
1162
  is_recebimento = (pagina_id == "recebimento")
1163
+
1164
+ # 🔒 ANTI-TREMOR: incluir telas com logo topo (login/quiz/primeira tela)
1165
+ is_login_or_quiz = (not st.session_state.get("logado")) or (not st.session_state.get("quiz_verificado"))
1166
+
1167
  interval_sec = int(st.session_state.get("__auto_refresh_interval_sec__", 60))
1168
+ if (interval_sec > 0) and not (is_inbox_admin or is_outlook_rel or is_formulario or is_recebimento or is_login_or_quiz):
1169
  st_autorefresh(interval=interval_sec * 1000, key=f"sidebar_autorefresh_{interval_sec}s")
1170
  except Exception:
1171
  pass