mirror of
https://github.com/shadoll/moma.git
synced 2026-08-28 03:27:34 +00:00
feat: Add delete file functionality with confirmation screen
This commit is contained in:
@@ -57,6 +57,8 @@ ACTIONS:
|
||||
• s: Scan - Refresh the current directory
|
||||
• f: Refresh - Reload metadata for selected file
|
||||
• r: Rename - Rename selected file with proposed name
|
||||
• c: Convert - Convert AVI file to MKV container with metadata
|
||||
• d: Delete - Delete selected file (with confirmation)
|
||||
• p: Expand/Collapse - Toggle expansion of selected directory
|
||||
• m: Toggle Mode - Switch between technical and catalog display modes
|
||||
• ctrl+s: Settings - Open settings window
|
||||
@@ -495,5 +497,110 @@ Do you want to proceed with conversion?
|
||||
# Simulate convert button press
|
||||
convert_button = self.query_one("#convert")
|
||||
self.on_button_pressed(type('Event', (), {'button': convert_button})())
|
||||
elif event.key == "n" or event.key == "escape":
|
||||
self.app.pop_screen() # type: ignore
|
||||
|
||||
|
||||
class DeleteConfirmScreen(Screen):
|
||||
"""Confirmation screen for file deletion."""
|
||||
|
||||
CSS = """
|
||||
#delete_content {
|
||||
text-align: center;
|
||||
}
|
||||
Button:focus {
|
||||
background: $primary;
|
||||
}
|
||||
#buttons {
|
||||
align: center middle;
|
||||
}
|
||||
#file_details {
|
||||
text-align: left;
|
||||
margin: 1 2;
|
||||
padding: 1 2;
|
||||
border: solid $error;
|
||||
}
|
||||
#warning_content {
|
||||
text-align: center;
|
||||
margin-bottom: 1;
|
||||
margin-top: 1;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, file_path: Path):
|
||||
super().__init__()
|
||||
self.file_path = file_path
|
||||
|
||||
def compose(self):
|
||||
from .formatters.text_formatter import TextFormatter
|
||||
|
||||
title_text = f"{TextFormatter.bold(TextFormatter.red('DELETE FILE'))}"
|
||||
|
||||
# Build file details
|
||||
file_size = self.file_path.stat().st_size if self.file_path.exists() else 0
|
||||
from .formatters.size_formatter import SizeFormatter
|
||||
size_str = SizeFormatter.format_size_full(file_size)
|
||||
|
||||
details_lines = [
|
||||
f"{TextFormatter.bold('File:')} {TextFormatter.cyan(escape(self.file_path.name))}",
|
||||
f"{TextFormatter.bold('Path:')} {TextFormatter.grey(escape(str(self.file_path.parent)))}",
|
||||
f"{TextFormatter.bold('Size:')} {TextFormatter.yellow(size_str)}",
|
||||
]
|
||||
|
||||
details_text = "\n".join(details_lines)
|
||||
|
||||
warning_text = f"""
|
||||
{TextFormatter.bold(TextFormatter.red("WARNING: This action cannot be undone!"))}
|
||||
{TextFormatter.yellow("The file will be permanently deleted from your system.")}
|
||||
|
||||
Are you sure you want to delete this file?
|
||||
""".strip()
|
||||
|
||||
with Center():
|
||||
with Vertical():
|
||||
yield Static(title_text, id="delete_content", markup=True)
|
||||
yield Static(details_text, id="file_details", markup=True)
|
||||
yield Static(warning_text, id="warning_content", markup=True)
|
||||
with Horizontal(id="buttons"):
|
||||
yield Button("No (n)", id="cancel", variant="primary")
|
||||
yield Button("Yes (y)", id="delete", variant="error")
|
||||
|
||||
def on_mount(self):
|
||||
# Set focus to "No" button by default (safer option)
|
||||
self.set_focus(self.query_one("#cancel"))
|
||||
|
||||
def on_button_pressed(self, event):
|
||||
if event.button.id == "delete":
|
||||
# Delete the file
|
||||
app = self.app # type: ignore
|
||||
|
||||
try:
|
||||
if self.file_path.exists():
|
||||
self.file_path.unlink()
|
||||
app.notify(f"✓ Deleted: {self.file_path.name}", severity="information", timeout=3)
|
||||
logging.info(f"File deleted: {self.file_path}")
|
||||
|
||||
# Remove from tree
|
||||
app.remove_file_from_tree(self.file_path)
|
||||
else:
|
||||
app.notify(f"✗ File not found: {self.file_path.name}", severity="error", timeout=3)
|
||||
|
||||
except PermissionError:
|
||||
app.notify(f"✗ Permission denied: Cannot delete {self.file_path.name}", severity="error", timeout=5)
|
||||
logging.error(f"Permission denied deleting file: {self.file_path}")
|
||||
except Exception as e:
|
||||
app.notify(f"✗ Error deleting file: {e}", severity="error", timeout=5)
|
||||
logging.error(f"Error deleting file {self.file_path}: {e}", exc_info=True)
|
||||
|
||||
self.app.pop_screen() # type: ignore
|
||||
else:
|
||||
# Cancel
|
||||
self.app.pop_screen() # type: ignore
|
||||
|
||||
def on_key(self, event):
|
||||
if event.key == "y":
|
||||
# Simulate delete button press
|
||||
delete_button = self.query_one("#delete")
|
||||
self.on_button_pressed(type('Event', (), {'button': delete_button})())
|
||||
elif event.key == "n" or event.key == "escape":
|
||||
self.app.pop_screen() # type: ignore
|
||||
Reference in New Issue
Block a user