Changed the modal size and also modified the edit_entry_screen.py to conform with the wireframe, also changed all the texts to be english

This commit is contained in:
Gustavo Henrique Santos Souza de Miranda
2025-06-25 00:27:49 -03:00
parent f9ab6da116
commit a999a0a437
8 changed files with 128 additions and 116 deletions
+5 -5
View File
@@ -5,7 +5,7 @@ from textual.widgets import Header, Footer, Button, Label, TextArea
from textual.containers import Container
class AboutScreen(Screen[bool]):
"""Tela para exibir informações sobre a aplicação."""
"""Screen to display application information."""
TITLE = "Pilgrim - About"
@@ -51,20 +51,20 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
yield self.footer
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Lida com os cliques dos botões."""
"""Handles button clicks."""
if "about-close-button" in event.button.classes:
self.dismiss(False)
elif "about-info-button" in event.button.classes:
self.notify("Mais informações seriam exibidas aqui!", title="Info")
self.notify("More information would be displayed here!", title="Info")
def action_dismiss(self, **kwargs) -> None:
"""Fecha o about box usando dismiss.
"""Closes the about box using dismiss.
:param **kwargs:
"""
self.dismiss(False)
def on_key(self, event) -> None:
"""Intercepta teclas específicas."""
"""Intercepts specific keys."""
if event.key == "escape":
self.dismiss(False)
event.prevent_default()
+42 -42
View File
@@ -58,31 +58,31 @@ class DiaryListScreen(Screen):
yield self.footer
def on_mount(self) -> None:
# Usa versão síncrona para o mount inicial
# Uses synchronous version for initial mount
self.refresh_diaries()
self.update_buttons_state()
def refresh_diaries(self):
"""Versão síncrona do refresh"""
"""Synchronous version of refresh"""
try:
service_manager = self.app.service_manager
travel_diary_service = service_manager.get_travel_diary_service()
# Usa método síncrono
# Uses synchronous method
diaries = travel_diary_service.read_all()
# Salva o estado atual
# Saves current state
current_diary_id = None
if (self.selected_diary_index is not None and
self.selected_diary_index in self.diary_id_map):
current_diary_id = self.diary_id_map[self.selected_diary_index]
# Limpa e reconstrói
# Clears and rebuilds
self.diary_list.clear_options()
self.diary_id_map = {}
if not diaries:
self.diary_list.add_option("[dim]Nenhum diário encontrado. Pressione 'N' para criar um novo![/dim]")
self.diary_list.add_option("[dim]No diaries found. Press 'N' to create a new one![/dim]")
self.selected_diary_index = None
else:
new_selected_index = 0
@@ -91,33 +91,33 @@ class DiaryListScreen(Screen):
self.diary_id_map[index] = diary.id
self.diary_list.add_option(f"[b]{diary.name}[/b]\n[dim]ID: {diary.id}[/dim]")
# Mantém a seleção se possível
# Maintains selection if possible
if current_diary_id and diary.id == current_diary_id:
new_selected_index = index
self.selected_diary_index = new_selected_index
# Atualiza o highlight
# Updates highlight
self.set_timer(0.05, lambda: self._update_highlight(new_selected_index))
# Força refresh visual
# Forces visual refresh
self.diary_list.refresh()
self.update_buttons_state()
except Exception as e:
self.notify(f"Erro ao carregar diários: {str(e)}")
self.notify(f"Error loading diaries: {str(e)}")
def _update_highlight(self, index: int):
"""Atualiza o highlight do OptionList"""
"""Updates the OptionList highlight"""
try:
if index < len(self.diary_list.options):
self.diary_list.highlighted = index
self.diary_list.refresh()
except Exception as e:
self.notify(f"Erro ao atualizar highlight: {str(e)}")
self.notify(f"Error updating highlight: {str(e)}")
async def async_refresh_diaries(self):
"""Versão assíncrona do refresh"""
"""Async version of refresh"""
if self.is_refreshing:
return
@@ -127,21 +127,21 @@ class DiaryListScreen(Screen):
service_manager = self.app.service_manager
travel_diary_service = service_manager.get_travel_diary_service()
# Usa método assíncrono
# Uses async method
diaries = await travel_diary_service.async_read_all()
# Salva o estado atual
# Saves current state
current_diary_id = None
if (self.selected_diary_index is not None and
self.selected_diary_index in self.diary_id_map):
current_diary_id = self.diary_id_map[self.selected_diary_index]
# Limpa e reconstrói
# Clears and rebuilds
self.diary_list.clear_options()
self.diary_id_map = {}
if not diaries:
self.diary_list.add_option("[dim]Nenhum diário encontrado. Pressione 'N' para criar um novo![/dim]")
self.diary_list.add_option("[dim]No diaries found. Press 'N' to create a new one![/dim]")
self.selected_diary_index = None
else:
new_selected_index = 0
@@ -160,12 +160,12 @@ class DiaryListScreen(Screen):
self.update_buttons_state()
except Exception as e:
self.notify(f"Erro ao carregar diários: {str(e)}")
self.notify(f"Error loading diaries: {str(e)}")
finally:
self.is_refreshing = False
def on_option_list_option_highlighted(self, event: OptionList.OptionHighlighted) -> None:
"""Handle quando uma opção é destacada"""
"""Handle when an option is highlighted"""
if self.diary_id_map and event.option_index in self.diary_id_map:
self.selected_diary_index = event.option_index
else:
@@ -174,7 +174,7 @@ class DiaryListScreen(Screen):
self.update_buttons_state()
def on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
"""Handle quando uma opção é selecionada"""
"""Handle when an option is selected"""
if self.diary_id_map and event.option_index in self.diary_id_map:
self.selected_diary_index = event.option_index
self.action_open_diary()
@@ -184,7 +184,7 @@ class DiaryListScreen(Screen):
self.update_buttons_state()
def update_buttons_state(self):
"""Atualiza o estado dos botões"""
"""Updates button states"""
has_selection = (self.selected_diary_index is not None and
self.selected_diary_index in self.diary_id_map)
@@ -192,7 +192,7 @@ class DiaryListScreen(Screen):
self.open_diary.disabled = not has_selection
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Handle cliques nos botões"""
"""Handle button clicks"""
button_id = event.button.id
if button_id == "new_diary":
@@ -203,7 +203,7 @@ class DiaryListScreen(Screen):
self.action_open_diary()
def action_new_diary(self):
"""Ação para criar novo diário"""
"""Action to create new diary"""
self.app.push_screen(NewDiaryModal(),self._on_new_diary_submitted)
def _on_new_diary_submitted(self,result):
@@ -231,7 +231,7 @@ class DiaryListScreen(Screen):
def action_edit_selected_diary(self):
"""Ação para editar diário selecionado"""
"""Action to edit selected diary"""
if self.selected_diary_index is not None:
diary_id = self.diary_id_map.get(self.selected_diary_index)
if diary_id:
@@ -240,10 +240,10 @@ class DiaryListScreen(Screen):
self._on_edited_diary_name_submitted
)
else:
self.notify("Selecione um diário para editar")
self.notify("Select a diary to edit")
def action_open_diary(self):
"""Ação para abrir diário selecionado"""
"""Action to open selected diary"""
if self.selected_diary_index is not None:
diary_id = self.diary_id_map.get(self.selected_diary_index)
if diary_id:
@@ -252,43 +252,43 @@ class DiaryListScreen(Screen):
else:
self.notify("Invalid diary ID")
else:
self.notify("Selecione um diário para abrir")
self.notify("Select a diary to open")
def _on_edited_diary_name_submitted(self, result: Optional[Tuple[int, str]]) -> None:
"""Callback após edição do diário"""
"""Callback after diary editing"""
if result:
diary_id, name = result
self.notify(f"Atualizando diário ID {diary_id} para '{name}'...")
# Agenda a atualização assíncrona
self.notify(f"Updating diary ID {diary_id} to '{name}'...")
# Schedules async update
self.call_later(self._async_update_diary, diary_id, name)
else:
self.notify("Edição cancelada")
self.notify("Edit canceled")
async def _async_update_diary(self, diary_id: int, name: str):
"""Atualiza o diário de forma assíncrona"""
"""Updates the diary asynchronously"""
try:
service = self.app.service_manager.get_travel_diary_service()
updated_diary = await service.async_update(diary_id, name)
if updated_diary:
self.notify(f"Diário '{name}' atualizado!")
# Força refresh após a atualização
self.notify(f"Diary '{name}' updated!")
# Forces refresh after update
await self.async_refresh_diaries()
else:
self.notify("Erro: Diário não encontrado")
self.notify("Error: Diary not found")
except Exception as e:
self.notify(f"Erro ao atualizar: {str(e)}")
self.notify(f"Error updating: {str(e)}")
def action_force_refresh(self):
"""Força refresh manual"""
self.notify("Forçando refresh...")
# Tenta ambas as versões
self.refresh_diaries() # Síncrona
self.call_later(self.async_refresh_diaries) # Assíncrona
"""Forces manual refresh"""
self.notify("Forcing refresh...")
# Tries both versions
self.refresh_diaries() # Synchronous
self.call_later(self.async_refresh_diaries) # Asynchronous
def action_open_selected_diary(self):
"""Ação do binding ENTER"""
"""Action for ENTER binding"""
self.action_open_diary()
def action_about_cmd(self):
+10 -11
View File
@@ -6,29 +6,28 @@ from textual.widgets import Label, Input, Button
class EditDiaryModal(ModalScreen[tuple[int,str]]):
BINDINGS = [
("escape", "cancel", "Cancelar"),
("escape", "cancel", "Cancel"),
]
def __init__(self, diary_id: int):
super().__init__()
self.diary_id = diary_id
self.current_diary_name = self.app.service_manager.get_travel_diary_service().read_by_id(self.diary_id).name
self.name_input = Input(value=self.current_diary_name, id="edit_diary_name_input",classes="EditDiaryModal-NameInput")
self.name_input = Input(value=self.current_diary_name, id="edit_diary_name_input", classes="EditDiaryModal-NameInput")
def compose(self) -> ComposeResult:
with Vertical(id="edit_diary_dialog", classes="EditDiaryModal-Dialog"):
yield Label(f"Editar Diário: {self.current_diary_name}", classes="EditDiaryModal-Title")
yield Label("Novo Nome do Diário:")
yield Label("Edit Diary", classes="EditDiaryModal-Title")
yield Label("New Diary Name:")
yield self.name_input
with Horizontal(classes="dialog-buttons"):
yield Button("Salvar", variant="primary", id="save_diary_button")
yield Button("Cancelar", variant="default", id="cancel_button")
with Horizontal(classes="EditDiaryModal-ButtonsContainer"):
yield Button("Save", variant="primary", id="save_diary_button", classes="EditDiaryModal-SaveButton")
yield Button("Cancel", variant="default", id="cancel_button", classes="EditDiaryModal-CancelButton")
def on_mount(self) -> None:
"""Foca no campo de entrada e move o cursor para o final do texto."""
"""Focuses on the input field and moves cursor to the end of text."""
self.name_input.focus()
self.name_input.cursor_position = len(self.name_input.value)
# REMOVIDA A LINHA QUE CAUSA O ERRO: self.name_input.select_text()
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "save_diary_button":
@@ -36,10 +35,10 @@ class EditDiaryModal(ModalScreen[tuple[int,str]]):
if new_diary_name and new_diary_name != self.current_diary_name:
self.dismiss((self.diary_id, new_diary_name))
elif new_diary_name == self.current_diary_name:
self.notify("Nenhuma alteração feita.", severity="warning")
self.notify("No changes made.", severity="warning")
self.dismiss(None)
else:
self.notify("O nome do diário não pode estar vazio.", severity="warning")
self.notify("Diary name cannot be empty.", severity="warning")
self.name_input.focus()
elif event.button.id == "cancel_button":
self.dismiss(None)
+26 -13
View File
@@ -14,21 +14,20 @@ from pilgrim.ui.screens.rename_entry_modal import RenameEntryModal
class EditEntryScreen(Screen):
TITLE = "Pilgrim - Edit Entry"
TITLE = "Pilgrim - Edit"
BINDINGS = [
Binding("ctrl+s", "save", "Save"),
Binding("ctrl+n", "next_entry", "Next/New Entry"),
Binding("ctrl+b", "prev_entry", "Previous Entry"),
Binding("ctrl+r", "rename_entry", "Rename Entry"),
Binding("escape", "back_to_list", "Back to List"),
Binding("r", "force_refresh", "Force refresh"),
Binding("escape", "back_to_list", "Back to List")
]
def __init__(self, diary_id: int = 1):
super().__init__()
self.diary_id = diary_id
self.diary_name = "Unknown Diary"
self.diary_name = f"Diary {diary_id}" # Use a better default name
self.current_entry_index = 0
self.entries: List[Entry] = []
self.is_new_entry = False
@@ -81,8 +80,7 @@ class EditEntryScreen(Screen):
"""Called when the screen is mounted"""
# First update diary info, then refresh entries
self.update_diary_info()
# Use a small delay to ensure diary info is loaded before refreshing entries
self.set_timer(0.1, self.refresh_entries)
self.refresh_entries()
def update_diary_info(self):
"""Updates diary information"""
@@ -94,11 +92,27 @@ class EditEntryScreen(Screen):
if diary:
self.diary_name = diary.name
self.diary_info.update(f"Diary: {self.diary_name}")
self.notify(f"Loaded diary: {self.diary_name}")
else:
self.notify(f"Diary with ID {self.diary_id} not found")
# If diary not found, try to get a default name
self.diary_name = f"Diary {self.diary_id}"
self.diary_info.update(f"Diary: {self.diary_name}")
self.notify(f"Diary {self.diary_id} not found, using default name")
except Exception as e:
# If there's an error, use a default name but don't break the app
self.diary_name = f"Diary {self.diary_id}"
self.diary_info.update(f"Diary: {self.diary_name}")
self.notify(f"Error loading diary info: {str(e)}")
# Always ensure the diary info is updated
self._ensure_diary_info_updated()
def _ensure_diary_info_updated(self):
"""Ensures the diary info widget is always updated with current diary name"""
try:
self.diary_info.update(f"Diary: {self.diary_name}")
except Exception as e:
# If even this fails, at least try to show something
self.diary_info.update(f"Diary: {self.diary_id}")
def refresh_entries(self):
"""Synchronous version of refresh"""
@@ -124,6 +138,9 @@ class EditEntryScreen(Screen):
except Exception as e:
self.notify(f"Error loading entries: {str(e)}")
# Ensure diary info is updated even if entries fail to load
self._ensure_diary_info_updated()
async def async_refresh_entries(self):
"""Asynchronous version of refresh"""
@@ -178,7 +195,7 @@ class EditEntryScreen(Screen):
self._update_status_indicator("New", "new")
else:
current_entry = self.entries[self.current_entry_index]
entry_text = f"Entry: ({self.current_entry_index + 1}/{len(self.entries)}) {current_entry.title}"
entry_text = f"Entry: \\[{self.current_entry_index + 1}/{len(self.entries)}] {current_entry.title}"
self.entry_info.update(entry_text)
self._update_status_indicator("Saved", "saved")
@@ -198,10 +215,6 @@ class EditEntryScreen(Screen):
def _update_entry_display(self):
"""Updates the display of the current entry"""
if not self.entries and not self.is_new_entry:
# Ensure diary name is loaded
if self.diary_name == "Unknown Diary":
self.update_diary_info()
self.text_entry.text = f"No entries found for diary '{self.diary_name}'\n\nPress Ctrl+N to create a new entry."
self.text_entry.read_only = True
self._original_content = self.text_entry.text
+3 -3
View File
@@ -27,17 +27,17 @@ class NewDiaryModal(ModalScreen[str]):
self.name_input.focus()
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Lida com os cliques dos botões."""
"""Handles button clicks."""
if event.button.id == "create_diary_button":
diary_name = self.name_input.value.strip()
if diary_name:
self.dismiss(diary_name)
else:
self.notify("O nome do diário não pode estar vazio.", severity="warning")
self.notify("Diary name cannot be empty.", severity="warning")
self.name_input.focus()
elif event.button.id == "cancel_button":
self.dismiss("")
def action_cancel(self) -> None:
"""Ação para cancelar a modal."""
"""Action to cancel the modal."""
self.dismiss("")
+1 -1
View File
@@ -22,7 +22,7 @@ class UIApp(App):
def on_mount(self) -> None:
"""Chamado quando a app inicia. Carrega a tela principal."""
"""Called when the app starts. Loads the main screen."""
self.push_screen(DiaryListScreen())
def get_system_commands(self, screen: Screen) -> Iterable[SystemCommand]: