Skip to content

Commit cc8585f

Browse files
committed
Qrcode and info page
1 parent b1bebb2 commit cc8585f

File tree

6 files changed

+99
-6
lines changed

6 files changed

+99
-6
lines changed

src/database_management.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ pub fn show_qr_code(index: usize) -> Result<(),String> {
211211
};
212212
pw.zeroize();
213213
if let Some(element) = elements.get(index - 1) {
214-
println!("{}",element.get_otp_code());
214+
println!("{}",element.get_qrcode());
215215
Ok(())
216216
}
217217
else {

src/interface/app.rs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use std::error;
22

33
use tui::backend::Backend;
4-
use tui::layout::{Constraint, Direction, Layout};
4+
use tui::layout::{Alignment, Constraint, Direction, Layout};
55
use tui::style::{Color, Modifier, Style};
66
use tui::terminal::Frame;
7-
use tui::widgets::{Block, Borders, Cell, Gauge, Row, Table};
7+
use tui::widgets::{Block, Borders, Cell, Gauge, Paragraph, Row, Table, Wrap};
8+
use crate::interface::page::Page;
9+
use crate::interface::page::Page::{MainPage,QrcodePage,InfoPage};
810

911
use crate::otp::otp_element::OTPElement;
1012
use crate::interface::table::{fill_table, StatefulTable};
@@ -21,8 +23,10 @@ pub struct App {
2123
pub(crate) table: StatefulTable,
2224
pub(crate) elements: Vec<OTPElement>,
2325
progress: u16,
26+
/// Text to print replacing the percentage
2427
pub(crate) label_text: String,
2528
pub(crate) print_percentage: bool,
29+
pub(crate) current_page: Page,
2630
}
2731

2832
impl App {
@@ -31,7 +35,7 @@ impl App {
3135
let mut title = String::from(env!("CARGO_PKG_NAME"));
3236
title.push_str(" v");
3337
title.push_str(env!("CARGO_PKG_VERSION"));
34-
Self { running: true, title, table: StatefulTable::new(&elements), elements, progress: percentage(),label_text: String::from(""), print_percentage: true, }
38+
Self { running: true, title, table: StatefulTable::new(&elements), elements, progress: percentage(),label_text: String::from(""), print_percentage: true, current_page: MainPage,}
3539
}
3640

3741
/// Handles the tick event of the terminal.
@@ -49,6 +53,63 @@ impl App {
4953

5054
/// Renders the user interface widgets.
5155
pub fn render<B: Backend>(&mut self, frame: &mut Frame<'_, B>) {
56+
match &self.current_page {
57+
MainPage => self.render_table(frame),
58+
QrcodePage => self.render_qrcode_page(frame),
59+
InfoPage => self.render_info_page(frame),
60+
}
61+
}
62+
63+
fn render_info_page<B: Backend>(&self, frame: &mut Frame<'_, B>) {
64+
let text = "Press:\n+ -> Increment the HOTP counter\n- -> Decrement the HOTP counter\n
65+
k -> Show QRCode of the selected element\nEnter -> Copy the OTP Code to the clipboard\nq, CTRL-D, Esc -> Exit the application";
66+
let paragraph = Paragraph::new(text)
67+
.block(Block::default().title(self.title.as_str()).borders(Borders::ALL))
68+
.style(Style::default().fg(Color::White).bg(Color::Black))
69+
.alignment(Alignment::Center)
70+
.wrap(Wrap { trim: true });
71+
self.render_paragraph(frame,paragraph);
72+
}
73+
74+
fn render_qrcode_page<B: Backend>(&self, frame: &mut Frame<'_, B>) {
75+
let paragraph = if let Some(i) = self.table.state.selected() {
76+
if let Some(element) = self.elements.get(i) {
77+
let title = format!("{} - {}",element.issuer(),element.label());
78+
Paragraph::new(element.get_qrcode())
79+
.block(Block::default().title(title).borders(Borders::ALL))
80+
.style(Style::default().fg(Color::White).bg(Color::Black))
81+
.alignment(Alignment::Center)
82+
.wrap(Wrap { trim: true })
83+
}
84+
else {
85+
Paragraph::new("No element is selected")
86+
.block(Block::default().title("Nope").borders(Borders::ALL))
87+
.style(Style::default().fg(Color::White).bg(Color::Black))
88+
.alignment(Alignment::Center)
89+
.wrap(Wrap { trim: true })
90+
}
91+
92+
}
93+
else {
94+
Paragraph::new("No element is selected")
95+
.block(Block::default().title("Nope").borders(Borders::ALL))
96+
.style(Style::default().fg(Color::White).bg(Color::Black))
97+
.alignment(Alignment::Center)
98+
.wrap(Wrap { trim: true })
99+
};
100+
self.render_paragraph(frame,paragraph);
101+
}
102+
103+
fn render_paragraph<B: Backend>(&self, frame: &mut Frame<'_, B>,paragraph: Paragraph) {
104+
let rects = Layout::default()
105+
.direction(Direction::Vertical)
106+
.constraints([Constraint::Percentage(100)].as_ref())
107+
.split(frame.size());
108+
109+
frame.render_widget(paragraph, rects[0]);
110+
}
111+
112+
fn render_table<B: Backend>(&mut self, frame: &mut Frame<'_, B>) {
52113
let rects = Layout::default()
53114
.direction(Direction::Vertical)
54115
.constraints([Constraint::Percentage(95), Constraint::Percentage(5)].as_ref())
@@ -107,4 +168,5 @@ impl App {
107168
frame.render_stateful_widget(t, rects[0], &mut self.table.state);
108169
frame.render_widget(progress_bar, rects[1]);
109170
}
171+
110172
}

src/interface/handler.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
33
use crate::interface::app::{App, AppResult};
44
use copypasta_ext::prelude::*;
55
use copypasta_ext::x11_fork::ClipboardContext;
6+
use crate::interface::page::Page::{InfoPage, MainPage, QrcodePage};
67

78
/// Handles the key events and updates the state of [`App`].
89
pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
@@ -25,22 +26,44 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
2526
// Move into the table
2627
KeyCode::Up => {
2728
app.print_percentage = true;
29+
app.current_page = MainPage;
2830
app.table.previous();
2931
}
3032

3133
KeyCode::Down => {
3234
app.print_percentage = true;
35+
app.current_page = MainPage;
3336
app.table.next();
3437
}
3538

3639
KeyCode::Char('+') => {
40+
app.current_page = MainPage;
3741
handle_counter_switch(app,true);
3842
}
3943

4044
KeyCode::Char('-') => {
45+
app.current_page = MainPage;
4146
handle_counter_switch(app, false);
4247
}
4348

49+
KeyCode::Char('k') | KeyCode::Char('K') => {
50+
if app.current_page == QrcodePage {
51+
app.current_page = MainPage
52+
}
53+
else {
54+
app.current_page = QrcodePage;
55+
}
56+
}
57+
58+
KeyCode::Char('i') | KeyCode::Char('I') => {
59+
if app.current_page == InfoPage {
60+
app.current_page = MainPage
61+
}
62+
else {
63+
app.current_page = InfoPage;
64+
}
65+
}
66+
4467
KeyCode::Enter => {
4568
if let Some(selected) = app.table.state.selected(){
4669
if let Some(element) = app.table.items.get(selected){
@@ -52,6 +75,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
5275
Err(_) => app.label_text = String::from("Cannot copy"),
5376
}
5477
app.print_percentage = false;
78+
app.current_page = MainPage;
5579
}
5680
}
5781
}

src/interface/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ pub mod app;
22
pub mod event;
33
pub mod handler;
44
pub mod table;
5-
pub mod ui;
5+
pub mod ui;
6+
mod page;

src/interface/page.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[derive(PartialEq)]
2+
pub enum Page {
3+
MainPage,
4+
QrcodePage,
5+
InfoPage,
6+
}

src/otp/otp_element.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl OTPElement {
106106
uri
107107
}
108108

109-
pub fn get_otp_code(&self) -> String {
109+
pub fn get_qrcode(&self) -> String {
110110
QrCode::new(&self.get_otpauth_uri()).unwrap().render::<unicode::Dense1x2>()
111111
.dark_color(unicode::Dense1x2::Light)
112112
.light_color(unicode::Dense1x2::Dark)

0 commit comments

Comments
 (0)