feat: basic entry selection
This commit is contained in:
parent
2fd3b41e03
commit
95bfede1e0
1 changed files with 64 additions and 14 deletions
|
|
@ -22,6 +22,10 @@ enum Message {
|
||||||
OpenDb,
|
OpenDb,
|
||||||
DbOpened(Result<keepass::Database, String>),
|
DbOpened(Result<keepass::Database, String>),
|
||||||
|
|
||||||
|
SelectionChanged(usize),
|
||||||
|
SelectionUp,
|
||||||
|
SelectionDown,
|
||||||
|
|
||||||
FocusNext,
|
FocusNext,
|
||||||
FocusPrevious,
|
FocusPrevious,
|
||||||
}
|
}
|
||||||
|
|
@ -33,6 +37,9 @@ struct State {
|
||||||
|
|
||||||
db: Option<keepass::Database>,
|
db: Option<keepass::Database>,
|
||||||
|
|
||||||
|
db_view: Vec<keepass::db::Entry>,
|
||||||
|
selected_entry: usize,
|
||||||
|
|
||||||
password: String,
|
password: String,
|
||||||
|
|
||||||
is_secure: bool,
|
is_secure: bool,
|
||||||
|
|
@ -88,6 +95,10 @@ impl State {
|
||||||
match result {
|
match result {
|
||||||
Ok(db) => {
|
Ok(db) => {
|
||||||
self.error = "".into();
|
self.error = "".into();
|
||||||
|
self.db_view = db
|
||||||
|
.iter_all_entries()
|
||||||
|
.map(|entry_ref| entry_ref.clone())
|
||||||
|
.collect();
|
||||||
self.db = Some(db)
|
self.db = Some(db)
|
||||||
}
|
}
|
||||||
Err(e) => self.error = e.into(),
|
Err(e) => self.error = e.into(),
|
||||||
|
|
@ -95,6 +106,20 @@ impl State {
|
||||||
self.status = "".into();
|
self.status = "".into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::SelectionChanged(val) => self.selected_entry = val,
|
||||||
|
Message::SelectionUp => {
|
||||||
|
self.selected_entry =
|
||||||
|
dbg!((self.selected_entry.wrapping_sub(1)).clamp(0, self.db_view.len() - 1))
|
||||||
|
}
|
||||||
|
Message::SelectionDown => {
|
||||||
|
self.selected_entry = if self.selected_entry == self.db_view.len() - 1 {
|
||||||
|
// essentially do a wrapping_add up to the highest index in the view
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
dbg!((self.selected_entry.wrapping_add(1)).clamp(0, self.db_view.len() - 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message::FocusNext => return widget::operation::focus_next(),
|
Message::FocusNext => return widget::operation::focus_next(),
|
||||||
Message::FocusPrevious => return widget::operation::focus_previous(),
|
Message::FocusPrevious => return widget::operation::focus_previous(),
|
||||||
}
|
}
|
||||||
|
|
@ -102,21 +127,39 @@ impl State {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
fn view(&self) -> Element<'_> {
|
fn view(&self) -> Element<'_> {
|
||||||
let main = if let Some(db) = self.db.as_ref() {
|
let main = if !self.db_view.is_empty() {
|
||||||
widget::scrollable(widget::row([
|
widget::scrollable(
|
||||||
widget::column(db.iter_all_entries().map(|entry| {
|
widget::grid(self.db_view.iter().enumerate().flat_map(|(i, entry)| {
|
||||||
widget::text(entry.get_title().unwrap_or_default().to_string()).into()
|
[
|
||||||
|
widget::button(widget::text(entry.get_title().unwrap_or_default()))
|
||||||
|
.style(if i == self.selected_entry {
|
||||||
|
widget::button::primary
|
||||||
|
} else {
|
||||||
|
widget::button::subtle
|
||||||
|
})
|
||||||
|
.on_press(Message::SelectionChanged(i))
|
||||||
|
.into(),
|
||||||
|
widget::button(widget::text(entry.get_username().unwrap_or_default()))
|
||||||
|
.style(if i == self.selected_entry {
|
||||||
|
widget::button::primary
|
||||||
|
} else {
|
||||||
|
widget::button::subtle
|
||||||
|
})
|
||||||
|
.on_press(Message::SelectionChanged(i))
|
||||||
|
.into(),
|
||||||
|
widget::button(widget::text(entry.get_url().unwrap_or_default()))
|
||||||
|
.style(if i == self.selected_entry {
|
||||||
|
widget::button::primary
|
||||||
|
} else {
|
||||||
|
widget::button::subtle
|
||||||
|
})
|
||||||
|
.on_press(Message::SelectionChanged(i))
|
||||||
|
.into(),
|
||||||
|
]
|
||||||
}))
|
}))
|
||||||
.into(),
|
.height(Length::Shrink)
|
||||||
widget::column(db.iter_all_entries().map(|entry| {
|
.columns(3),
|
||||||
widget::text(entry.get_username().unwrap_or_default().to_string()).into()
|
)
|
||||||
}))
|
|
||||||
.into(),
|
|
||||||
widget::column(db.iter_all_entries().map(|entry| {
|
|
||||||
widget::text(entry.get_url().unwrap_or_default().to_string()).into()
|
|
||||||
}))
|
|
||||||
.into(),
|
|
||||||
]))
|
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
widget::container(
|
widget::container(
|
||||||
|
|
@ -195,6 +238,13 @@ impl State {
|
||||||
}
|
}
|
||||||
Key::Character("p" | "f" | "i") if !db_loaded => Some(Message::PickDb),
|
Key::Character("p" | "f" | "i") if !db_loaded => Some(Message::PickDb),
|
||||||
|
|
||||||
|
Key::Character("k") | Key::Named(key::Named::ArrowUp) => {
|
||||||
|
Some(Message::SelectionUp)
|
||||||
|
}
|
||||||
|
Key::Character("j") | Key::Named(key::Named::ArrowDown) => {
|
||||||
|
Some(Message::SelectionDown)
|
||||||
|
}
|
||||||
|
|
||||||
// ignore unused keys
|
// ignore unused keys
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue