treewide: fix various UI bugs; optimize crypto dependencies & format

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: If8fe8b38c1d9c4fecd40ff71f88d2ae06a6a6964
This commit is contained in:
raf 2026-02-10 12:56:05 +03:00
commit 3ccddce7fd
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
178 changed files with 58285 additions and 54241 deletions

View file

@ -3,148 +3,179 @@ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use crate::app::View;
pub enum Action {
Quit,
NavigateUp,
NavigateDown,
NavigateLeft,
NavigateRight,
Select,
Back,
Search,
Import,
Delete,
DeleteSelected,
Open,
TagView,
CollectionView,
AuditView,
SettingsView,
DuplicatesView,
DatabaseView,
QueueView,
StatisticsView,
TasksView,
ScanTrigger,
Refresh,
NextTab,
PrevTab,
PageUp,
PageDown,
GoTop,
GoBottom,
CreateTag,
TagMedia,
UntagMedia,
Help,
Edit,
Vacuum,
Toggle,
RunNow,
Save,
Char(char),
Backspace,
// Multi-select actions
ToggleSelection,
SelectAll,
ClearSelection,
ToggleSelectionMode,
BatchDelete,
BatchTag,
None,
Quit,
NavigateUp,
NavigateDown,
NavigateLeft,
NavigateRight,
Select,
Back,
Search,
Import,
Delete,
DeleteSelected,
Open,
TagView,
CollectionView,
AuditView,
SettingsView,
DuplicatesView,
DatabaseView,
QueueView,
StatisticsView,
TasksView,
ScanTrigger,
Refresh,
NextTab,
PrevTab,
PageUp,
PageDown,
GoTop,
GoBottom,
CreateTag,
TagMedia,
UntagMedia,
Help,
Edit,
Vacuum,
Toggle,
RunNow,
Save,
Char(char),
Backspace,
// Multi-select actions
ToggleSelection,
SelectAll,
ClearSelection,
ToggleSelectionMode,
BatchDelete,
BatchTag,
None,
}
pub fn handle_key(key: KeyEvent, in_input_mode: bool, current_view: &View) -> Action {
if in_input_mode {
match (key.code, key.modifiers) {
(KeyCode::Esc, _) => Action::Back,
(KeyCode::Enter, _) => Action::Select,
(KeyCode::Char('s'), KeyModifiers::CONTROL) => match current_view {
View::MetadataEdit => Action::Save,
_ => Action::Select,
},
(KeyCode::Char(c), _) => Action::Char(c),
(KeyCode::Backspace, _) => Action::Backspace,
_ => Action::None,
}
} else {
match (key.code, key.modifiers) {
(KeyCode::Char('q'), _) | (KeyCode::Char('c'), KeyModifiers::CONTROL) => Action::Quit,
(KeyCode::Up | KeyCode::Char('k'), _) => Action::NavigateUp,
(KeyCode::Down | KeyCode::Char('j'), _) => Action::NavigateDown,
(KeyCode::Left | KeyCode::Char('h'), _) => Action::NavigateLeft,
(KeyCode::Right | KeyCode::Char('l'), _) => Action::NavigateRight,
(KeyCode::Home, _) => Action::GoTop,
(KeyCode::End, _) => Action::GoBottom,
(KeyCode::Enter, _) => Action::Select,
(KeyCode::Esc, _) => Action::Back,
(KeyCode::Char('/'), _) => Action::Search,
(KeyCode::Char('?'), _) => Action::Help,
(KeyCode::Char('i'), _) => Action::Import,
(KeyCode::Char('d'), _) => match current_view {
View::Tags | View::Collections => Action::DeleteSelected,
_ => Action::Delete,
},
(KeyCode::Char('o'), _) => Action::Open,
(KeyCode::Char('e'), _) => match current_view {
View::Detail => Action::Edit,
_ => Action::None,
},
(KeyCode::Char('t'), _) => match current_view {
View::Tasks => Action::Toggle,
_ => Action::TagView,
},
(KeyCode::Char('c'), _) => Action::CollectionView,
// Multi-select: Ctrl+A for SelectAll (must come before plain 'a')
(KeyCode::Char('a'), KeyModifiers::CONTROL) => match current_view {
View::Library | View::Search => Action::SelectAll,
_ => Action::None,
},
(KeyCode::Char('a'), _) => Action::AuditView,
(KeyCode::Char('S'), _) => Action::SettingsView,
(KeyCode::Char('B'), _) => Action::DatabaseView,
(KeyCode::Char('Q'), _) => Action::QueueView,
(KeyCode::Char('X'), _) => Action::StatisticsView,
// Use plain D/T for views in non-library contexts, keep for batch ops in library/search
(KeyCode::Char('D'), _) => match current_view {
View::Library | View::Search => Action::BatchDelete,
_ => Action::DuplicatesView,
},
(KeyCode::Char('T'), _) => match current_view {
View::Library | View::Search => Action::BatchTag,
_ => Action::TasksView,
},
// Ctrl+S must come before plain 's' to ensure proper precedence
(KeyCode::Char('s'), KeyModifiers::CONTROL) => match current_view {
View::MetadataEdit => Action::Save,
_ => Action::None,
},
(KeyCode::Char('s'), _) => Action::ScanTrigger,
(KeyCode::Char('r'), _) => Action::Refresh,
(KeyCode::Char('n'), _) => Action::CreateTag,
(KeyCode::Char('+'), _) => Action::TagMedia,
(KeyCode::Char('-'), _) => Action::UntagMedia,
(KeyCode::Char('v'), _) => match current_view {
View::Database => Action::Vacuum,
_ => Action::ToggleSelectionMode,
},
(KeyCode::Char('x'), _) => match current_view {
View::Tasks => Action::RunNow,
_ => Action::None,
},
(KeyCode::Tab, _) => Action::NextTab,
(KeyCode::BackTab, _) => Action::PrevTab,
(KeyCode::PageUp, _) => Action::PageUp,
(KeyCode::PageDown, _) => Action::PageDown,
// Multi-select keys
(KeyCode::Char(' '), _) => match current_view {
View::Library | View::Search => Action::ToggleSelection,
_ => Action::None,
},
(KeyCode::Char('u'), _) => match current_view {
View::Library | View::Search => Action::ClearSelection,
_ => Action::None,
},
_ => Action::None,
pub fn handle_key(
key: KeyEvent,
in_input_mode: bool,
current_view: &View,
) -> Action {
if in_input_mode {
match (key.code, key.modifiers) {
(KeyCode::Esc, _) => Action::Back,
(KeyCode::Enter, _) => Action::Select,
(KeyCode::Char('s'), KeyModifiers::CONTROL) => {
match current_view {
View::MetadataEdit => Action::Save,
_ => Action::Select,
}
},
(KeyCode::Char(c), _) => Action::Char(c),
(KeyCode::Backspace, _) => Action::Backspace,
_ => Action::None,
}
} else {
match (key.code, key.modifiers) {
(KeyCode::Char('q'), _) | (KeyCode::Char('c'), KeyModifiers::CONTROL) => {
Action::Quit
},
(KeyCode::Up | KeyCode::Char('k'), _) => Action::NavigateUp,
(KeyCode::Down | KeyCode::Char('j'), _) => Action::NavigateDown,
(KeyCode::Left | KeyCode::Char('h'), _) => Action::NavigateLeft,
(KeyCode::Right | KeyCode::Char('l'), _) => Action::NavigateRight,
(KeyCode::Home, _) => Action::GoTop,
(KeyCode::End, _) => Action::GoBottom,
(KeyCode::Enter, _) => Action::Select,
(KeyCode::Esc, _) => Action::Back,
(KeyCode::Char('/'), _) => Action::Search,
(KeyCode::Char('?'), _) => Action::Help,
(KeyCode::Char('i'), _) => Action::Import,
(KeyCode::Char('d'), _) => {
match current_view {
View::Tags | View::Collections => Action::DeleteSelected,
_ => Action::Delete,
}
},
(KeyCode::Char('o'), _) => Action::Open,
(KeyCode::Char('e'), _) => {
match current_view {
View::Detail => Action::Edit,
_ => Action::None,
}
},
(KeyCode::Char('t'), _) => {
match current_view {
View::Tasks => Action::Toggle,
_ => Action::TagView,
}
},
(KeyCode::Char('c'), _) => Action::CollectionView,
// Multi-select: Ctrl+A for SelectAll (must come before plain 'a')
(KeyCode::Char('a'), KeyModifiers::CONTROL) => {
match current_view {
View::Library | View::Search => Action::SelectAll,
_ => Action::None,
}
},
(KeyCode::Char('a'), _) => Action::AuditView,
(KeyCode::Char('S'), _) => Action::SettingsView,
(KeyCode::Char('B'), _) => Action::DatabaseView,
(KeyCode::Char('Q'), _) => Action::QueueView,
(KeyCode::Char('X'), _) => Action::StatisticsView,
// Use plain D/T for views in non-library contexts, keep for batch ops in
// library/search
(KeyCode::Char('D'), _) => {
match current_view {
View::Library | View::Search => Action::BatchDelete,
_ => Action::DuplicatesView,
}
},
(KeyCode::Char('T'), _) => {
match current_view {
View::Library | View::Search => Action::BatchTag,
_ => Action::TasksView,
}
},
// Ctrl+S must come before plain 's' to ensure proper precedence
(KeyCode::Char('s'), KeyModifiers::CONTROL) => {
match current_view {
View::MetadataEdit => Action::Save,
_ => Action::None,
}
},
(KeyCode::Char('s'), _) => Action::ScanTrigger,
(KeyCode::Char('r'), _) => Action::Refresh,
(KeyCode::Char('n'), _) => Action::CreateTag,
(KeyCode::Char('+'), _) => Action::TagMedia,
(KeyCode::Char('-'), _) => Action::UntagMedia,
(KeyCode::Char('v'), _) => {
match current_view {
View::Database => Action::Vacuum,
_ => Action::ToggleSelectionMode,
}
},
(KeyCode::Char('x'), _) => {
match current_view {
View::Tasks => Action::RunNow,
_ => Action::None,
}
},
(KeyCode::Tab, _) => Action::NextTab,
(KeyCode::BackTab, _) => Action::PrevTab,
(KeyCode::PageUp, _) => Action::PageUp,
(KeyCode::PageDown, _) => Action::PageDown,
// Multi-select keys
(KeyCode::Char(' '), _) => {
match current_view {
View::Library | View::Search => Action::ToggleSelection,
_ => Action::None,
}
},
(KeyCode::Char('u'), _) => {
match current_view {
View::Library | View::Search => Action::ClearSelection,
_ => Action::None,
}
},
_ => Action::None,
}
}
}