mirror of https://github.com/gmbrax/Pilgrim.git
				
				
				
			
						commit
						ca14588a1d
					
				|  | @ -33,30 +33,30 @@ class EntryServiceMock(EntryService): | |||
|         } | ||||
|         self._next_id = 11 | ||||
| 
 | ||||
|     # Métodos síncronos (mantidos para compatibilidade) | ||||
|     # Synchronous methods (kept for compatibility) | ||||
|     def create(self, travel_diary_id: int, title: str, text: str, date: str) -> Entry: | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         new_entry = Entry(title, text, date, travel_diary_id, id=self._next_id) | ||||
|         self.mock_data[self._next_id] = new_entry | ||||
|         self._next_id += 1 | ||||
|         return new_entry | ||||
| 
 | ||||
|     def read_by_id(self, entry_id: int) -> Entry | None: | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         return self.mock_data.get(entry_id) | ||||
| 
 | ||||
|     def read_all(self) -> List[Entry]: | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         return list(self.mock_data.values()) | ||||
| 
 | ||||
|     def read_by_travel_diary_id(self, travel_diary_id: int) -> List[Entry]: | ||||
|         """Versão síncrona - lê entradas por diário""" | ||||
|         """Synchronous version - reads entries by diary""" | ||||
|         return [entry for entry in self.mock_data.values() if entry.fk_travel_diary_id == travel_diary_id] | ||||
| 
 | ||||
|     def read_paginated(self, travel_diary_id: int, page: int = 1, page_size: int = 5) -> Tuple[List[Entry], int, int]: | ||||
|         """Versão síncrona - lê entradas paginadas por diário""" | ||||
|         """Synchronous version - reads paginated entries by diary""" | ||||
|         entries = self.read_by_travel_diary_id(travel_diary_id) | ||||
|         entries.sort(key=lambda x: x.id, reverse=True)  # Mais recentes primeiro | ||||
|         entries.sort(key=lambda x: x.id, reverse=True)  # Most recent first | ||||
|          | ||||
|         total_entries = len(entries) | ||||
|         total_pages = (total_entries + page_size - 1) // page_size | ||||
|  | @ -69,7 +69,7 @@ class EntryServiceMock(EntryService): | |||
|         return page_entries, total_pages, total_entries | ||||
| 
 | ||||
|     def update(self, entry_src: Entry, entry_dst: Entry) -> Entry | None: | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         item_to_update = self.mock_data.get(entry_src.id) | ||||
|         if item_to_update: | ||||
|             item_to_update.title = entry_dst.title if entry_dst.title is not None else item_to_update.title | ||||
|  | @ -83,41 +83,41 @@ class EntryServiceMock(EntryService): | |||
|         return None | ||||
| 
 | ||||
|     def delete(self, entry_src: Entry) -> Entry | None: | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         return self.mock_data.pop(entry_src.id, None) | ||||
| 
 | ||||
|     # Métodos assíncronos (principais) | ||||
|     # Async methods (main) | ||||
|     async def async_create(self, travel_diary_id: int, title: str, text: str, date: str) -> Entry: | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.create(travel_diary_id, title, text, date) | ||||
| 
 | ||||
|     async def async_read_by_id(self, entry_id: int) -> Entry | None: | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.read_by_id(entry_id) | ||||
| 
 | ||||
|     async def async_read_all(self) -> List[Entry]: | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.read_all() | ||||
| 
 | ||||
|     async def async_read_by_travel_diary_id(self, travel_diary_id: int) -> List[Entry]: | ||||
|         """Versão assíncrona - lê entradas por diário""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version - reads entries by diary""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.read_by_travel_diary_id(travel_diary_id) | ||||
| 
 | ||||
|     async def async_read_paginated(self, travel_diary_id: int, page: int = 1, page_size: int = 5) -> Tuple[List[Entry], int, int]: | ||||
|         """Versão assíncrona - lê entradas paginadas por diário""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version - reads paginated entries by diary""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.read_paginated(travel_diary_id, page, page_size) | ||||
| 
 | ||||
|     async def async_update(self, entry_src: Entry, entry_dst: Entry) -> Entry | None: | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.update(entry_src, entry_dst) | ||||
| 
 | ||||
|     async def async_delete(self, entry_src: Entry) -> Entry | None: | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.delete(entry_src) | ||||
|  | @ -12,24 +12,24 @@ class TravelDiaryServiceMock(TravelDiaryService): | |||
|         } | ||||
|         self._next_id = 3 | ||||
| 
 | ||||
|     # Métodos síncronos (originais) | ||||
|     # Synchronous methods (original) | ||||
|     def create(self, name: str): | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         new_travel_diary = TravelDiary(id=self._next_id, name=name) | ||||
|         self.mock_data[self._next_id] = new_travel_diary | ||||
|         self._next_id += 1 | ||||
|         return new_travel_diary | ||||
| 
 | ||||
|     def read_by_id(self, travel_id: int): | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         return self.mock_data.get(travel_id) | ||||
| 
 | ||||
|     def read_all(self): | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         return list(self.mock_data.values()) | ||||
| 
 | ||||
|     def update(self, travel_diary_id: int, name: str): | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         item_to_update = self.mock_data.get(travel_diary_id) | ||||
|         if item_to_update: | ||||
|             item_to_update.name = name | ||||
|  | @ -37,31 +37,31 @@ class TravelDiaryServiceMock(TravelDiaryService): | |||
|         return None | ||||
| 
 | ||||
|     def delete(self, travel_diary_id: int): | ||||
|         """Versão síncrona""" | ||||
|         """Synchronous version""" | ||||
|         return self.mock_data.pop(travel_diary_id, None) | ||||
| 
 | ||||
|     # Métodos assíncronos (novos) | ||||
|     # Async methods (new) | ||||
|     async def async_create(self, name: str): | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.create(name) | ||||
| 
 | ||||
|     async def async_read_by_id(self, travel_id: int): | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.read_by_id(travel_id) | ||||
| 
 | ||||
|     async def async_read_all(self): | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.read_all() | ||||
| 
 | ||||
|     async def async_update(self, travel_diary_id: int, name: str): | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.update(travel_diary_id, name) | ||||
| 
 | ||||
|     async def async_delete(self, travel_diary_id: int): | ||||
|         """Versão assíncrona""" | ||||
|         await asyncio.sleep(0.01)  # Simula I/O | ||||
|         """Async version""" | ||||
|         await asyncio.sleep(0.01)  # Simulates I/O | ||||
|         return self.delete(travel_diary_id) | ||||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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,44 +252,48 @@ 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): | ||||
|         self.app.push_screen(AboutScreen()) | ||||
| 
 | ||||
|     def action_quit(self): | ||||
|         """Action to quit the application""" | ||||
|         self.app.exit() | ||||
|  | @ -6,7 +6,7 @@ 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): | ||||
|  | @ -17,18 +17,17 @@ class EditDiaryModal(ModalScreen[tuple[int,str]]): | |||
| 
 | ||||
|     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) | ||||
|  |  | |||
|  | @ -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,12 +92,28 @@ 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""" | ||||
|         try: | ||||
|  | @ -125,6 +139,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""" | ||||
|         if self.is_refreshing: | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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("") | ||||
|  | @ -3,175 +3,7 @@ Screen { | |||
|     background: $surface-darken-1; | ||||
|     align: center middle; | ||||
| } | ||||
| .DiaryListScreen-DiaryListContainer { | ||||
|     height: 1fr; | ||||
|     width: 100%; | ||||
|     layout: vertical; | ||||
|     align: center top; /* Alinha no topo para seguir o wireframe */ | ||||
|     padding: 2 4; /* Mais espaço nas laterais */ | ||||
|     background: $surface; /* Removendo aquamarine para ficar mais limpo */ | ||||
| } | ||||
| 
 | ||||
| /* A lista de diários - área principal como no wireframe */ | ||||
| .DiaryListScreen-DiaryListOptions { | ||||
|     border: round $primary-lighten-2; | ||||
|     background: $surface; | ||||
|     width: 75%; /* Largura generosa como no wireframe */ | ||||
|     height: 72%; /* Ocupa o espaço disponível */ | ||||
|     margin: 2 0; /* Margem vertical para separar dos outros elementos */ | ||||
| } | ||||
| 
 | ||||
| .DiaryListScreen-DiaryListOptions:focus { | ||||
|     border: round $primary; | ||||
| } | ||||
| 
 | ||||
| /* O contêiner dos botões - logo abaixo da lista */ | ||||
| .DiaryListScreen-ButtonsGrid { | ||||
|     layout: horizontal; | ||||
|     align: center middle; | ||||
|     width: 79%; /* Mesma largura da lista */ | ||||
|     height: 20%; /* Aumentando altura para caber o texto dos botões */ | ||||
| } | ||||
| 
 | ||||
| /* Botões individuais - garantindo espaço para o texto */ | ||||
| .DiaryListScreen-NewDiaryButton, | ||||
| .DiaryListScreen-EditDiaryButton, | ||||
| .DiaryListScreen-OpenDiaryButton { | ||||
|     margin: 0 1 1 0; /* Espaço entre os botões */ | ||||
|     height: 1fr; | ||||
|     width: 1fr; | ||||
|     border: round grey; | ||||
| } | ||||
| 
 | ||||
| /* As dicas - usando a classe correta */ | ||||
| .DiaryListScreen-DiaryListTips { | ||||
|     width: 100%; /* Largura total quando usando dock */ | ||||
|     height: auto; | ||||
|     text-style: italic; | ||||
|     text-align: center; /* Centraliza o texto dentro do elemento */ | ||||
|     color: $text-muted; | ||||
|     dock: bottom; /* Gruda no fundo da tela */ | ||||
|     margin: 0 1; | ||||
| } | ||||
| 
 | ||||
| /* Estilos genéricos que não mudaram */ | ||||
| .option-list--option-highlighted { | ||||
|     background: $primary-darken-2; | ||||
| } | ||||
| 
 | ||||
| .option-list--option-selected { | ||||
|     text-style: bold; | ||||
|     background: $primary; | ||||
| } | ||||
| 
 | ||||
| Header { | ||||
|     background: $primary; | ||||
|     color: $text; | ||||
| } | ||||
| 
 | ||||
| Footer { | ||||
|     background: $primary; | ||||
|     color: $text; | ||||
| } | ||||
| 
 | ||||
| AboutScreen { | ||||
|     align: center middle; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutContainer { | ||||
|     align: center middle; | ||||
|     width: 85%; | ||||
|     height: 95%; | ||||
|     border: thick $primary; | ||||
|     background: $surface; | ||||
|     margin: 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutContainer TextArea { | ||||
|     align: center middle; | ||||
|     width: 100%; | ||||
|     height: 55%; | ||||
|     margin: 2; | ||||
|     padding: 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_SubContainer { | ||||
|     align: center middle; | ||||
|     height: 45%; | ||||
|     padding: 1 1; | ||||
|     margin: 1 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutTitle { | ||||
|     color: $accent; | ||||
|     text-style: bold; | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutVersion { | ||||
|     color: $warning; | ||||
|     text-style: italic; | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutContent { | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutContact, | ||||
| .AboutScreen_AboutAuthor { | ||||
|     color: $text-muted; | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .AboutScreen_AboutLicense { | ||||
|     height: 60%; | ||||
| } | ||||
| 
 | ||||
| Screen.-modal { | ||||
|     background: rgba(0, 0, 0, 0.7); /* Escurece o fundo da tela por baixo */ | ||||
|     align: center middle; /* Centraliza o conteúdo (sua modal) que está nesta tela modal */ | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-Dialog { | ||||
|     width: 60%; /* Largura do diálogo */ | ||||
|     height: auto; /* Altura automática */ | ||||
|     background: $surface; /* Fundo do diálogo */ | ||||
|     border: thick $accent; /* Borda chamativa */ | ||||
|     padding: 2 4; /* Espaçamento interno */ | ||||
|     align: center middle; /* Centraliza conteúdo dentro do diálogo */ | ||||
|     layout: vertical; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-Dialog .NewDiaryModal-Title{ | ||||
|     text-align: center; | ||||
|     text-style: bold; | ||||
|     color: $primary; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-NameInput{ | ||||
|     width: 1fr; /* Ocupa a largura disponível */ | ||||
|     margin-bottom: 2; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-ButtonsContainer{ | ||||
|     width: 1fr; | ||||
|     height: auto; | ||||
|     align: center middle; | ||||
|     padding-top: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-ButtonsContainer Button{ | ||||
|     margin: 0 1; | ||||
|     width: 1fr; | ||||
| } | ||||
| 
 | ||||
| /* EditEntryScreen Styles */ | ||||
| .EditEntryScreen-sub-header { | ||||
|     layout: horizontal; | ||||
|     background: $primary-darken-1; | ||||
|  | @ -234,7 +66,294 @@ Screen.-modal { | |||
|     border: none; | ||||
| } | ||||
| 
 | ||||
| /* RenameEntryModal Styles */ | ||||
| AboutScreen { | ||||
|     align: center middle; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutContainer { | ||||
|     align: center middle; | ||||
|     width: 85%; | ||||
|     height: 95%; | ||||
|     border: thick $primary; | ||||
|     background: $surface; | ||||
|     margin: 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutContainer TextArea { | ||||
|     align: center middle; | ||||
|     width: 100%; | ||||
|     height: 55%; | ||||
|     margin: 2; | ||||
|     padding: 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_SubContainer { | ||||
|     align: center middle; | ||||
|     height: 45%; | ||||
|     padding: 1 1; | ||||
|     margin: 1 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutTitle { | ||||
|     color: $accent; | ||||
|     text-style: bold; | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutVersion { | ||||
|     color: $warning; | ||||
|     text-style: italic; | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutContent { | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutContact, | ||||
| #AboutScreen_AboutAuthor { | ||||
|     color: $text-muted; | ||||
|     text-align: center; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| #AboutScreen_AboutLicense { | ||||
|     height: 60%; | ||||
| } | ||||
| 
 | ||||
| /* Main container - distributing vertical space */ | ||||
| .DiaryListScreen-DiaryListContainer { | ||||
|     height: 1fr; | ||||
|     width: 100%; | ||||
|     layout: vertical; | ||||
|     align: center top; /* Aligns at the top to follow the wireframe */ | ||||
|     padding: 2 4; /* More space on the sides */ | ||||
|     background: $surface; /* Removing aquamarine to keep it cleaner */ | ||||
| } | ||||
| 
 | ||||
| /* Diary list - main area as in the wireframe */ | ||||
| .DiaryListScreen-DiaryListOptions { | ||||
|     border: round $primary-lighten-2; | ||||
|     background: $surface; | ||||
|     width: 75%; /* Generous width as in the wireframe */ | ||||
|     height: 60%; /* Occupies available space */ | ||||
|     margin: 2 0; /* Vertical margin to separate from other elements */ | ||||
| } | ||||
| 
 | ||||
| .DiaryListScreen-DiaryListOptions:focus { | ||||
|     border: round $primary; | ||||
| } | ||||
| 
 | ||||
| /* Button container - right below the list */ | ||||
| .DiaryListScreen-ButtonsGrid { | ||||
|     layout: horizontal; | ||||
|     align: center middle; | ||||
|     width: 75%; /* Same width as the diary list */ | ||||
|     height: 20%; /* Increasing height to fit button text */ | ||||
| } | ||||
| 
 | ||||
| /* Individual buttons - ensuring space for text */ | ||||
| .DiaryListScreen-NewDiaryButton, | ||||
| .DiaryListScreen-EditDiaryButton, | ||||
| .DiaryListScreen-OpenDiaryButton { | ||||
|     margin: 0 1 1 0; /* Space between buttons */ | ||||
|     height: 1fr; | ||||
|     width: 1fr; | ||||
|     border: round grey; | ||||
|     text-align: center; | ||||
|     content-align: center middle; | ||||
| } | ||||
| 
 | ||||
| /* Tips - using the correct class */ | ||||
| .DiaryListScreen-DiaryListTips { | ||||
|     width: 100%; /* Full width when using dock */ | ||||
|     height: auto; | ||||
|     text-style: italic; | ||||
|     text-align: center; /* Centers text within the element */ | ||||
|     color: $text-muted; | ||||
|     dock: bottom; /* Sticks to the bottom of the screen */ | ||||
|     margin: 0 1; | ||||
| } | ||||
| 
 | ||||
| /* Generic styles that haven't changed */ | ||||
| .option-list--option-highlighted { | ||||
|     background: $primary-darken-2; | ||||
| } | ||||
| 
 | ||||
| .option-list--option-selected { | ||||
|     text-style: bold; | ||||
|     background: $primary; | ||||
| } | ||||
| 
 | ||||
| Header { | ||||
|     background: $primary; | ||||
|     color: $text; | ||||
| } | ||||
| 
 | ||||
| Footer { | ||||
|     background: $primary; | ||||
|     color: $text; | ||||
| } | ||||
| 
 | ||||
| Screen.-modal { | ||||
|     background: rgba(0, 0, 0, 0.7); /* Darkens the background screen underneath */ | ||||
|     align: center middle; /* Centers the content (your modal) that is in this modal screen */ | ||||
| } | ||||
| 
 | ||||
| /* Style for the new diary modal dialog */ | ||||
| .NewDiaryModal-dialog { | ||||
|     layout: vertical; | ||||
|     width: 60%; | ||||
|     height: auto; | ||||
|     background: $surface; | ||||
|     border: thick $accent; | ||||
|     padding: 2 4; | ||||
|     align: center middle; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-title { | ||||
|     text-align: center; | ||||
|     text-style: bold; | ||||
|     color: $primary; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-label { | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-name-input { | ||||
|     width: 1fr; | ||||
|     margin-bottom: 2; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-buttons { | ||||
|     width: 1fr; | ||||
|     height: auto; | ||||
|     align: center middle; | ||||
|     padding-top: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-buttons Button { | ||||
|     margin: 0 1; | ||||
|     width: 1fr; | ||||
| } | ||||
| 
 | ||||
| /* Additional classes for NewDiaryModal */ | ||||
| .NewDiaryModal-Dialog { | ||||
|     layout: vertical; | ||||
|     width: 60%; | ||||
|     height: auto; | ||||
|     background: $surface; | ||||
|     border: thick $accent; | ||||
|     padding: 2 4; | ||||
|     align: center middle; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-Title { | ||||
|     text-align: center; | ||||
|     text-style: bold; | ||||
|     color: $primary; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-NameInput { | ||||
|     width: 1fr; | ||||
|     margin-bottom: 2; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-ButtonsContainer { | ||||
|     width: 1fr; | ||||
|     height: auto; | ||||
|     align: center middle; | ||||
|     padding-top: 1; | ||||
| } | ||||
| 
 | ||||
| .NewDiaryModal-CreateDiaryButton, | ||||
| .NewDiaryModal-CancelButton { | ||||
|     margin: 0 1; | ||||
|     width: 1fr; | ||||
| } | ||||
| 
 | ||||
| /* Style for the edit diary modal dialog */ | ||||
| .EditDiaryModal-dialog { | ||||
|     layout: vertical; | ||||
|     width: 60%; | ||||
|     height: auto; | ||||
|     background: $surface; | ||||
|     border: thick $warning; | ||||
|     padding: 2 4; | ||||
|     align: center middle; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-title { | ||||
|     text-align: center; | ||||
|     text-style: bold; | ||||
|     color: $warning; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-label { | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-name-input { | ||||
|     width: 1fr; | ||||
|     margin-bottom: 2; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-buttons { | ||||
|     width: 1fr; | ||||
|     height: auto; | ||||
|     align: center middle; | ||||
|     padding-top: 1; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-buttons Button { | ||||
|     margin: 0 1; | ||||
|     width: 1fr; | ||||
| } | ||||
| 
 | ||||
| /* Additional classes for EditDiaryModal */ | ||||
| .EditDiaryModal-Dialog { | ||||
|     layout: vertical; | ||||
|     width: 60%; | ||||
|     height: auto; | ||||
|     background: $surface; | ||||
|     border: thick $warning; | ||||
|     padding: 2 4; | ||||
|     align: center middle; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-Title { | ||||
|     text-align: center; | ||||
|     text-style: bold; | ||||
|     color: $warning; | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-NameInput { | ||||
|     width: 1fr; | ||||
|     margin-bottom: 2; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-ButtonsContainer { | ||||
|     width: 1fr; | ||||
|     height: auto; | ||||
|     align: center middle; | ||||
|     padding-top: 1; | ||||
| } | ||||
| 
 | ||||
| .EditDiaryModal-SaveButton, | ||||
| .EditDiaryModal-CancelButton { | ||||
|     margin: 0 1; | ||||
|     width: 1fr; | ||||
| } | ||||
| 
 | ||||
| /* Style for the rename entry modal dialog */ | ||||
| .RenameEntryModal-dialog { | ||||
|     layout: vertical; | ||||
|     width: 60%; | ||||
|  | @ -252,10 +371,6 @@ Screen.-modal { | |||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .RenameEntryModal-label { | ||||
|     margin-bottom: 1; | ||||
| } | ||||
| 
 | ||||
| .RenameEntryModal-name-input { | ||||
|     width: 1fr; | ||||
|     margin-bottom: 2; | ||||
|  | @ -268,7 +383,8 @@ Screen.-modal { | |||
|     padding-top: 1; | ||||
| } | ||||
| 
 | ||||
| .RenameEntryModal-buttons Button { | ||||
| .RenameEntryModal-save-button, | ||||
| .RenameEntryModal-cancel-button { | ||||
|     margin: 0 1; | ||||
|     width: 1fr; | ||||
| }  | ||||
|  | @ -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]: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue