Skip to content

Commit

Permalink
added search state
Browse files Browse the repository at this point in the history
  • Loading branch information
maschad committed Jan 10, 2024
1 parent 3dbe598 commit dfafdf0
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 5 deletions.
93 changes: 89 additions & 4 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub enum InputMode {
Normal,
Editing,
}
use crate::{
models::states::InputMode,
routes::{ActiveBlock, Route},
};

// App holds the state of the application
pub struct App {
Expand All @@ -11,14 +11,99 @@ pub struct App {
pub messages: Vec<String>,
// Current input into search bar
pub input: String,
/// whether to show help dialogue
pub show_help: bool,
/// Position of the cursor
pub cursor_position: usize,
/// Current route
pub routes: Vec<Route>,
}

impl App {
pub fn default() -> App {
App {
cursor_position: 0,
input: "".to_owned(),
input_mode: InputMode::Normal,
messages: Vec::new(),
routes: vec![Route::default()],
show_help: false,
}
}

pub fn pop_current_route(&mut self) {
if self.routes.len() > 1 {
self.routes.pop();
}
}

pub fn get_current_route(&self) -> Route {
self.routes
.last()
.map_or(Route::default(), |route| route.to_owned())
}

pub fn set_route(&mut self, route: Route) {
self.routes.push(route);
}

pub fn change_active_block(&mut self, active_block: ActiveBlock) {
let current_route = self.get_current_route();
self.routes.pop();
self.routes
.push(Route::new(current_route.get_id(), active_block));
}

pub fn move_cursor_left(&mut self) {
let cursor_moved_left = self.cursor_position.saturating_sub(1);
self.cursor_position = self.clamp_cursor(cursor_moved_left);
}

pub fn move_cursor_right(&mut self) {
let cursor_moved_right = self.cursor_position.saturating_add(1);
self.cursor_position = self.clamp_cursor(cursor_moved_right);
}

pub fn enter_char(&mut self, new_char: char) {
self.input.insert(self.cursor_position, new_char);

self.move_cursor_right();
}

pub fn paste(&mut self, data: String) {
self.input = format!("{}{}", self.input, data);
for _ in 0..data.len() {
self.move_cursor_right();
}
}

pub fn delete_char(&mut self) {
let is_not_cursor_leftmost = self.cursor_position != 0;
if is_not_cursor_leftmost {
// Method "remove" is not used on the saved text for deleting the selected char.
// Reason: Using remove on String works on bytes instead of the chars.
// Using remove would require special care because of char boundaries.

let current_index = self.cursor_position;
let from_left_to_current_index = current_index - 1;

// Getting all characters before the selected character.
let before_char_to_delete = self.input.chars().take(from_left_to_current_index);
// Getting all characters after selected character.
let after_char_to_delete = self.input.chars().skip(current_index);

// Put all characters together except the selected one.
// By leaving the selected one out, it is forgotten and therefore deleted.
self.input = before_char_to_delete.chain(after_char_to_delete).collect();
self.move_cursor_left();
}
}

pub fn clamp_cursor(&self, new_cursor_pos: usize) -> usize {
new_cursor_pos.clamp(0, self.input.len())
}

pub fn reset_cursor(&mut self) {
self.cursor_position = 0;
}
}
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use std::sync::{mpsc, Arc};
use std::thread;
use std::time::{Duration, Instant};

use app::{App, InputMode};
use app::App;
use crossterm::{
event::{self, Event as CEvent, KeyCode},
terminal::{disable_raw_mode, enable_raw_mode},
};

use models::states::InputMode;
use ratatui::{
backend::CrosstermBackend,
layout::{Constraint, Direction, Layout},
Expand All @@ -23,6 +24,7 @@ use widgets::welcome::render_welcome;
mod app;
mod models;
mod network;
mod routes;
mod util;
mod widgets;

Expand Down
1 change: 1 addition & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod position;
pub mod states;
45 changes: 45 additions & 0 deletions src/models/states.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
pub enum InputMode {
Normal,
Editing,
}

pub struct Query {
pub query: String,
pub error_message: Option<String>,
}

pub struct AppSearchState {
pub current_search_query: String,
pub cursor_position: usize,
pub input_mode: InputMode,
pub is_invalid_search: bool,
pub is_blank_search: bool,
pub query: Option<Query>,
}

impl Default for AppSearchState {
fn default() -> Self {
AppSearchState {
current_search_query: "".to_owned(),
cursor_position: 0,
input_mode: InputMode::Normal,
is_invalid_search: false,
is_blank_search: false,
query: None,
}
}
}

impl AppSearchState {
/// Resets the [`AppSearchState`] to its default state, albeit still enabled.
pub fn reset(&mut self) {
*self = AppSearchState {
..AppSearchState::default()
}
}

/// Returns whether the [`AppSearchState`] has an invalid or blank search.
pub fn is_invalid_or_blank_search(&self) -> bool {
self.is_blank_search || self.is_invalid_search
}
}
40 changes: 40 additions & 0 deletions src/routes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#[derive(Clone)]
pub enum RouteId {
Welcome,
Searching(String),
}

#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ActiveBlock {
SearchBar,
Main,
}

#[derive(Clone)]
pub struct Route {
id: RouteId,
active_block: ActiveBlock,
}

impl Route {
pub fn new(id: RouteId, active_block: ActiveBlock) -> Self {
Self { id, active_block }
}

pub fn get_active_block(&self) -> ActiveBlock {
self.active_block
}

pub fn get_id(&self) -> RouteId {
self.id.to_owned()
}
}

impl Default for Route {
fn default() -> Self {
Self {
id: RouteId::Welcome,
active_block: ActiveBlock::SearchBar,
}
}
}

0 comments on commit dfafdf0

Please sign in to comment.