mirror of https://github.com/gmbrax/Pilgrim.git
118 lines
5.1 KiB
Python
118 lines
5.1 KiB
Python
from pathlib import Path
|
|
from textual.app import ComposeResult
|
|
from textual.screen import Screen
|
|
from textual.widgets import Static, Input, Button
|
|
from textual.containers import Horizontal, Container
|
|
from .file_picker_modal import FilePickerModal
|
|
|
|
class AddPhotoModal(Screen):
|
|
"""Modal for adding a new photo"""
|
|
def __init__(self, diary_id: int):
|
|
super().__init__()
|
|
self.diary_id = diary_id
|
|
self.result = None
|
|
self.created_photo = None
|
|
|
|
|
|
def compose(self) -> ComposeResult:
|
|
yield Container(
|
|
Static("📷 Add New Photo", classes="AddPhotoModal-Title"),
|
|
Static("File path:", classes="AddPhotoModal-Label"),
|
|
Horizontal(
|
|
Input(placeholder="Enter file path...", id="filepath-input", classes="AddPhotoModal-Input"),
|
|
Button("Escolher arquivo...", id="choose-file-button", classes="AddPhotoModal-Button"),
|
|
classes="AddPhotoModal-FileRow"
|
|
),
|
|
Static("Photo name:", classes="AddPhotoModal-Label"),
|
|
Input(placeholder="Enter photo name...", id="name-input", classes="AddPhotoModal-Input"),
|
|
Static("Caption (optional):", classes="AddPhotoModal-Label"),
|
|
Input(placeholder="Enter caption...", id="caption-input", classes="AddPhotoModal-Input"),
|
|
Horizontal(
|
|
Button("Add Photo", id="add-button", classes="AddPhotoModal-Button"),
|
|
Button("Cancel", id="cancel-button", classes="AddPhotoModal-Button"),
|
|
classes="AddPhotoModal-Buttons"
|
|
),
|
|
classes="AddPhotoModal-Dialog"
|
|
)
|
|
|
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
|
if event.button.id == "choose-file-button":
|
|
self.app.push_screen(
|
|
FilePickerModal(),
|
|
self.handle_file_picker_result
|
|
)
|
|
return
|
|
if event.button.id == "add-button":
|
|
filepath = self.query_one("#filepath-input", Input).value
|
|
name = self.query_one("#name-input", Input).value
|
|
caption = self.query_one("#caption-input", Input).value
|
|
if not filepath.strip() or not name.strip():
|
|
self.notify("File path and name are required", severity="error")
|
|
return
|
|
|
|
# Try to create the photo in the database
|
|
self.call_later(self._async_create_photo, {
|
|
"filepath": filepath.strip(),
|
|
"name": name.strip(),
|
|
"caption": caption.strip() if caption.strip() else None
|
|
})
|
|
elif event.button.id == "cancel-button":
|
|
self.dismiss()
|
|
|
|
async def _async_create_photo(self, photo_data: dict):
|
|
"""Creates a new photo asynchronously using PhotoService"""
|
|
|
|
|
|
try:
|
|
service_manager = self.app.service_manager
|
|
photo_service = service_manager.get_photo_service()
|
|
|
|
if photo_service.check_photo_by_hash(photo_service.hash_file(photo_data["filepath"]),self.diary_id):
|
|
self.notify("Photo already exists in database", severity="error")
|
|
return
|
|
|
|
new_photo = photo_service.create(
|
|
filepath=Path(photo_data["filepath"]),
|
|
name=photo_data["name"],
|
|
travel_diary_id=self.diary_id,
|
|
caption=photo_data["caption"]
|
|
)
|
|
|
|
if new_photo:
|
|
self.created_photo = new_photo
|
|
|
|
|
|
self.notify(f"Photo '{new_photo.name}' added successfully!\nHash: {new_photo.photo_hash[:8]}\nReference: \\[\\[photo:{new_photo.name}:{new_photo.photo_hash[:8]}\\]\\]",
|
|
severity="information", timeout=5)
|
|
|
|
# Return the created photo data to the calling screen
|
|
self.result = {
|
|
"filepath": photo_data["filepath"],
|
|
"name": photo_data["name"],
|
|
"caption": photo_data["caption"],
|
|
"photo_id": new_photo.id,
|
|
"hash": new_photo.photo_hash
|
|
}
|
|
self.dismiss(self.result)
|
|
else:
|
|
self.notify("Error creating photo in database", severity="error")
|
|
|
|
except Exception as e:
|
|
self.notify(f"Error creating photo: {str(e)}", severity="error")
|
|
|
|
def handle_file_picker_result(self, result: str | None) -> None:
|
|
if result:
|
|
# Set the filepath input value
|
|
filepath_input = self.query_one("#filepath-input", Input)
|
|
filepath_input.value = result
|
|
# Trigger the input change event to update the UI
|
|
filepath_input.refresh()
|
|
# Auto-fill the name field with the filename (without extension)
|
|
filename = Path(result).stem
|
|
name_input = self.query_one("#name-input", Input)
|
|
if not name_input.value.strip():
|
|
name_input.value = filename
|
|
name_input.refresh()
|
|
else:
|
|
# User cancelled the file picker
|
|
self.notify("File selection cancelled", severity="information") |