@danhachuel/thunderbolt 0.4.90 → 0.4.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/app/main.py +17 -26
  2. package/package.json +1 -1
package/app/main.py CHANGED
@@ -2025,7 +2025,7 @@ def render_tiktok_channels():
2025
2025
  for channel in channels:
2026
2026
  channel_id = str(channel.get("id") or "")
2027
2027
  with st.container(border=True):
2028
- card_cols = st.columns([0.7, 2.3, 1.0, 1.0, 1.35, 1.25])
2028
+ card_cols = st.columns([0.7, 3.45, 1.15, 1.15, 1.45, 1.55], gap="small")
2029
2029
  with card_cols[0]:
2030
2030
  avatar_url = _tiktok_avatar_url(channel)
2031
2031
  if avatar_url:
@@ -2041,9 +2041,6 @@ def render_tiktok_channels():
2041
2041
  st.metric("Seguidores", format_metric_number(channel.get("subscriber_count")))
2042
2042
  with card_cols[3]:
2043
2043
  st.metric("Curtidas", format_metric_number(channel.get("likes_count")))
2044
- with card_cols[4]:
2045
- current_prompt = str(channel.get("default_prompt_master") or channel.get("prompt_master") or "")
2046
- selected_prompt = st.selectbox("Prompt Master", prompt_ids, index=prompt_ids.index(current_prompt) if current_prompt in prompt_ids else 0, format_func=lambda item: prompt_labels.get(item, item), key=f"tiktok_import_card_prompt_{channel_id}")
2047
2044
  with card_cols[5]:
2048
2045
  active = st.toggle("Activo", value=bool(channel.get("active", True)), key=f"tiktok_import_card_active_{channel_id}")
2049
2046
  if active != bool(channel.get("active", True)):
@@ -2055,20 +2052,20 @@ def render_tiktok_channels():
2055
2052
  if st.button("Apagar card", key=f"tiktok_import_card_delete_{channel_id}"):
2056
2053
  st.session_state[f"tiktok_delete_{channel_id}"] = True
2057
2054
  st.rerun()
2058
- summary_cols = st.columns(4, gap="small")
2059
- with summary_cols[0]:
2060
- st.markdown("**Blueprint Padrão**")
2061
- st.caption(prompt_labels.get(str(channel.get("default_prompt_master") or channel.get("prompt_master") or ""), "Sem Blueprint padrão"))
2062
- with summary_cols[1]:
2063
- st.markdown("**Nicho**")
2064
- st.caption(channel_niche_label(channel))
2065
- with summary_cols[2]:
2066
- st.markdown("**Narrador/Voz Padrão**")
2067
- st.caption(str(channel.get("default_voice") or channel.get("voice") or "Sem voz padrão"))
2068
- with summary_cols[3]:
2069
- st.markdown("**Idioma**")
2070
- st.caption(video_language_label(normalize_video_language(channel.get("language") or "pt")))
2071
- st.caption(f"Fonte do vídeo: {channel_video_source_value(channel.get('style_wide'))} · Proporção: {channel.get('video_aspect_ratio') or 'Portrait 9:16'}")
2055
+ summary_cols = st.columns(4, gap="medium")
2056
+ with summary_cols[0]:
2057
+ st.markdown("**Blueprint Padrão**")
2058
+ st.caption(prompt_labels.get(str(channel.get("default_prompt_master") or channel.get("prompt_master") or ""), "Sem Blueprint padrão"))
2059
+ with summary_cols[1]:
2060
+ st.markdown("**Nicho**")
2061
+ st.caption(channel_niche_label(channel))
2062
+ with summary_cols[2]:
2063
+ st.markdown("**Narrador/Voz Padrão**")
2064
+ st.caption(str(channel.get("default_voice") or channel.get("voice") or "Sem voz padrão"))
2065
+ with summary_cols[3]:
2066
+ st.markdown("**Idioma**")
2067
+ st.caption(video_language_label(normalize_video_language(channel.get("language") or "pt")))
2068
+ st.caption(f"Fonte do vídeo: {channel_video_source_value(channel.get('style_wide'))} · Proporção: {channel.get('video_aspect_ratio') or 'Portrait 9:16'}")
2072
2069
  if st.session_state.get(f"tiktok_delete_{channel_id}"):
2073
2070
  st.warning("Apagar este canal TikTok e os dados locais associados?")
2074
2071
  confirm_cols = st.columns(2)
@@ -2081,13 +2078,6 @@ def render_tiktok_channels():
2081
2078
  if st.button("Cancelar", key=f"tiktok_cancel_delete_{channel_id}"):
2082
2079
  st.session_state.pop(f"tiktok_delete_{channel_id}", None)
2083
2080
  st.rerun()
2084
- if st.session_state.get(f"tiktok_niche_{channel_id}"):
2085
- with st.form(f"tiktok_niche_form_{channel_id}"):
2086
- niche_value = st.text_input("Nicho do canal", value=str(channel.get("niche") or ""))
2087
- if st.form_submit_button("Guardar nicho", type="primary"):
2088
- update_channel(channel_id, {"niche": niche_value.strip(), "reference_channels": [niche_value.strip()] if niche_value.strip() else []})
2089
- st.session_state.pop(f"tiktok_niche_{channel_id}", None)
2090
- st.rerun()
2091
2081
  if st.session_state.get(f"tiktok_edit_{channel_id}"):
2092
2082
  with st.form(f"tiktok_edit_form_{channel_id}"):
2093
2083
  edit_name = st.text_input("Nome do canal", value=str(channel.get("name") or ""))
@@ -2096,6 +2086,7 @@ def render_tiktok_channels():
2096
2086
  edit_language = st.selectbox("Idioma do roteiro", VIDEO_LANGUAGE_SELECTION_OPTIONS, index=VIDEO_LANGUAGE_SELECTION_OPTIONS.index(normalize_video_language(channel.get("language") or "pt")) if normalize_video_language(channel.get("language") or "pt") in VIDEO_LANGUAGE_SELECTION_OPTIONS else 0, format_func=video_language_label)
2097
2087
  edit_source = st.selectbox("Fonte do vídeo", WIDE_STYLE_OPTIONS, index=WIDE_STYLE_OPTIONS.index(channel_video_source_value(channel.get("style_wide"))) if channel_video_source_value(channel.get("style_wide")) in WIDE_STYLE_OPTIONS else 0)
2098
2088
  edit_aspect = st.selectbox("Proporção do vídeo", CHANNEL_ASPECT_RATIO_OPTIONS, index=CHANNEL_ASPECT_RATIO_OPTIONS.index(str(channel.get("video_aspect_ratio") or "Portrait 9:16")) if str(channel.get("video_aspect_ratio") or "Portrait 9:16") in CHANNEL_ASPECT_RATIO_OPTIONS else 1)
2089
+ edit_niche = st.text_input("Nicho", value=str(channel.get("niche") or ""))
2099
2090
  edit_voice = st.selectbox("Narrador/Voz Padrão", voice_options, index=voice_options.index(str(channel.get("default_voice") or channel.get("voice") or "")) if str(channel.get("default_voice") or channel.get("voice") or "") in voice_options else 0, format_func=lambda item: item or "Sem voz padrão")
2100
2091
  edit_automation = st.toggle("Automação ON", value=bool(channel.get("automation_on", False)), key=f"tiktok_edit_automation_{channel_id}")
2101
2092
  edit_time = st.text_input("Horário diário (HH:MM)", value=str(channel.get("automation_time") or "00:00"))
@@ -2105,7 +2096,7 @@ def render_tiktok_channels():
2105
2096
  if not valid_hhmm(edit_time):
2106
2097
  st.error("O horário diário deve estar no formato HH:MM.")
2107
2098
  else:
2108
- update_channel(channel_id, {"name": edit_name.strip(), "url": edit_url.strip(), "handle": edit_handle.strip(), "language": edit_language, "default_voice": edit_voice, "voice": edit_voice, "style_wide": channel_video_source_storage(edit_source), "video_aspect_ratio": edit_aspect, "automation_on": edit_automation, "automation_time": edit_time.strip(), "description": edit_description.strip(), "platform": "tiktok"})
2099
+ update_channel(channel_id, {"name": edit_name.strip(), "url": edit_url.strip(), "handle": edit_handle.strip(), "language": edit_language, "niche": edit_niche.strip(), "reference_channels": [edit_niche.strip()] if edit_niche.strip() else [], "default_voice": edit_voice, "voice": edit_voice, "style_wide": channel_video_source_storage(edit_source), "video_aspect_ratio": edit_aspect, "automation_on": edit_automation, "automation_time": edit_time.strip(), "description": edit_description.strip(), "platform": "tiktok"})
2109
2100
  st.session_state.pop(f"tiktok_edit_{channel_id}", None)
2110
2101
  st.rerun()
2111
2102
  with st.expander("Últimos 10 vídeos publicados", expanded=False):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.4.90",
3
+ "version": "0.4.91",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",