Skip to content

Commit

Permalink
Add warning before delete not empty dir (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Harunx9 committed Jan 24, 2021
1 parent 17bc30b commit f19686f
Show file tree
Hide file tree
Showing 14 changed files with 408 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sfm"
version = "0.1.1"
version = "0.1.2"
authors = ["Szymon <szwanot@gmail.com>"]
edition = "2018"
license-file = "LICENSE"
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,10 @@ Configuration file should be named `sfm.toml` and shoudl be placed in `~/` or `~

## Instalation

Right now you can clone this repo and perform `cargo run` I will come with a more convenient way in the future.
* Via Cargo

```bash
cargo install sfm

```

3 changes: 2 additions & 1 deletion src/app/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ pub enum FileAction {

#[derive(Clone, Debug)]
pub enum DirectoryAction {
Delete { panel: PanelInfo },
DeleteWithContent { panel: PanelInfo },
Delete { panel: PanelInfo, is_empty: bool },
Rename { from: PanelInfo, to: PanelInfo },
Move { from: PanelInfo, to: PanelInfo },
Open { panel: PanelInfo, in_new_tab: bool },
Expand Down
1 change: 1 addition & 0 deletions src/app/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use tui::layout::{Constraint, Direction, Layout, Rect};

pub mod create_modal;
pub mod error_modal;
pub mod not_empty_dir_delete_modal;
pub mod panel;
pub mod rename_modal;
pub mod root;
Expand Down
220 changes: 220 additions & 0 deletions src/app/components/not_empty_dir_delete_modal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
use tui::{
backend::Backend,
layout::Rect,
style::Style,
text::{Span, Spans},
widgets::{Block, Borders, Clear, List, ListItem, ListState},
Frame,
};

use crate::{
app::{
actions::{AppAction, PanelSide},
state::TabIdx,
},
core::{store::Store, ui::component_base::ComponentBase},
};
use crate::{
app::{
actions::{DirectoryAction, FileManagerActions, PanelInfo},
file_system::FileSystem,
state::AppState,
},
core::{events::Event, ui::component::Component},
};
use std::{fmt::Debug, marker::PhantomData, path::PathBuf};

use super::create_modal_layout;

#[derive(Clone, Default)]
pub struct NotEmptyDirDeleteModalComponentProps {
panel_side: Option<PanelSide>,
panel_tab: TabIdx,
path: PathBuf,
}

impl NotEmptyDirDeleteModalComponentProps {
pub fn new(panel_side: Option<PanelSide>, panel_tab: TabIdx, path: PathBuf) -> Self {
NotEmptyDirDeleteModalComponentProps {
panel_side,
panel_tab,
path,
}
}
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Options {
Ok,
Cancel,
}

impl ToString for Options {
fn to_string(&self) -> String {
match self {
Options::Ok => "Ok".to_string(),
Options::Cancel => "Cancel".to_string(),
}
}
}

impl From<String> for Options {
fn from(source: String) -> Self {
match source.as_str() {
"Ok" => Options::Ok,
"Cancel" => Options::Cancel,
_ => panic!(""),
}
}
}

impl From<usize> for Options {
fn from(source: usize) -> Self {
match source {
0 => Options::Ok,
1 => Options::Cancel,
_ => panic!(""),
}
}
}

#[derive(Clone, Default)]
pub struct NotEmptyDirDeleteModalComponentState {
list_state: ListState,
}

pub struct NotEmptyDirDeleteModalComponent<TFileSystem: Clone + Debug + Default + FileSystem> {
base: ComponentBase<NotEmptyDirDeleteModalComponentProps, NotEmptyDirDeleteModalComponentState>,
_marker: PhantomData<TFileSystem>,
}

impl<TFileSystem: Clone + Debug + Default + FileSystem>
NotEmptyDirDeleteModalComponent<TFileSystem>
{
pub fn new(props: NotEmptyDirDeleteModalComponentProps) -> Self {
NotEmptyDirDeleteModalComponent {
base: ComponentBase::new(
Some(props),
Some(NotEmptyDirDeleteModalComponentState::default()),
),
_marker: PhantomData,
}
}
}

impl<TFileSystem: Clone + Debug + Default + FileSystem>
Component<Event, AppState<TFileSystem>, FileManagerActions>
for NotEmptyDirDeleteModalComponent<TFileSystem>
{
fn handle_event(
&mut self,
event: Event,
store: &mut Store<AppState<TFileSystem>, FileManagerActions>,
) -> bool {
let state = store.get_state();
let local_state = self.base.get_state().unwrap();
if let Event::Keyboard(key_evt) = event {
if state.config.keyboard_cfg.move_up.is_pressed(key_evt) {
let next_item = match local_state.list_state.selected() {
Some(current) => {
if current == 0 {
2
} else {
current - 1
}
}
None => 0,
};
self.base.set_state(|mut current_state| {
current_state.list_state.select(Some(next_item));
NotEmptyDirDeleteModalComponentState {
list_state: current_state.list_state,
..current_state
}
});
return true;
}

if state.config.keyboard_cfg.move_down.is_pressed(key_evt) {
let next_item = match local_state.list_state.selected() {
Some(current) => {
if current >= 2 {
0
} else {
current + 1
}
}
None => 0,
};
self.base.set_state(|mut current_state| {
current_state.list_state.select(Some(next_item));
NotEmptyDirDeleteModalComponentState {
list_state: current_state.list_state,
..current_state
}
});
return true;
}

if state.config.keyboard_cfg.accept.is_pressed(key_evt) {
if let Some(selected) = local_state.list_state.selected() {
let props = self.base.get_props().unwrap();
let option = Options::from(selected);
match option {
Options::Ok => store.dispatch(FileManagerActions::Directory(
DirectoryAction::DeleteWithContent {
panel: PanelInfo {
side: props.panel_side.unwrap(),
tab: props.panel_tab,
path: props.path,
},
},
)),
_ => {}
}
store.dispatch(FileManagerActions::App(AppAction::CloseModal));
}
}

if state.config.keyboard_cfg.close.is_pressed(key_evt) {
store.dispatch(FileManagerActions::App(AppAction::CloseModal));
return true;
}
}
false
}

fn render<TBackend: Backend>(&self, frame: &mut Frame<TBackend>, area: Option<Rect>) {
let layout = if let Some(area) = area {
create_modal_layout(50, 10, area)
} else {
create_modal_layout(50, 10, frame.size())
};

let mut local_state = self.base.get_state().unwrap();

let items = vec![
ListItem::new(Spans::from(vec![Span::from(Options::Ok.to_string())])),
ListItem::new(Spans::from(vec![Span::from(Options::Cancel.to_string())])),
];

let block = Block::default()
.title(Spans::from(vec![
Span::from("| "),
Span::from("This directory is not empty do you want to remove it ?"),
Span::from(" |"),
]))
.borders(Borders::ALL)
.border_style(Style::default())
.border_type(tui::widgets::BorderType::Thick)
.style(Style::default().bg(tui::style::Color::Reset));

let list = List::new(items)
.block(block)
.highlight_style(Style::default())
.highlight_symbol(">>");

frame.render_widget(Clear, layout);
frame.render_stateful_widget(list, layout, &mut local_state.list_state);
}
}
54 changes: 54 additions & 0 deletions src/app/components/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ use crate::{
use super::{
create_modal::{CreateModalComponent, CreateModalProps},
error_modal::{ErrorModalComponent, ErrorModalComponentProps},
not_empty_dir_delete_modal::{
NotEmptyDirDeleteModalComponent, NotEmptyDirDeleteModalComponentProps,
},
panel::PanelComponent,
rename_modal::{RenameModalComponent, RenameModalComponentProps},
};
Expand All @@ -36,6 +39,7 @@ pub struct RootComponent<TFileSystem: Clone + Debug + Default + FileSystem> {
create_modal: Option<CreateModalComponent<TFileSystem>>,
rename_modal: Option<RenameModalComponent<TFileSystem>>,
error_modal: Option<ErrorModalComponent<TFileSystem>>,
non_empty_dir_delete_modal: Option<NotEmptyDirDeleteModalComponent<TFileSystem>>,
_maker: std::marker::PhantomData<TFileSystem>,
}

Expand All @@ -48,6 +52,7 @@ impl<TFileSystem: Clone + Debug + Default + FileSystem> RootComponent<TFileSyste
create_modal: None,
rename_modal: None,
error_modal: None,
non_empty_dir_delete_modal: None,
_maker: std::marker::PhantomData,
}
}
Expand Down Expand Up @@ -113,6 +118,22 @@ impl<TFileSystem: Clone + Debug + Default + FileSystem> RootComponent<TFileSyste
));
}
}
ModalType::DeleteDirWithContent {
panel_side,
panel_tab,
path,
} => {
if self.non_empty_dir_delete_modal.is_none() {
self.non_empty_dir_delete_modal =
Some(NotEmptyDirDeleteModalComponent::new(
NotEmptyDirDeleteModalComponentProps::new(
Some(panel_side),
panel_tab,
path,
),
));
}
}
};
}
if self.create_modal.is_some() && state.modal.is_none() {
Expand All @@ -126,6 +147,10 @@ impl<TFileSystem: Clone + Debug + Default + FileSystem> RootComponent<TFileSyste
if self.error_modal.is_some() && state.modal.is_none() {
self.error_modal = None;
}

if self.non_empty_dir_delete_modal.is_some() && state.modal.is_none() {
self.non_empty_dir_delete_modal = None;
}
}
}

Expand Down Expand Up @@ -155,6 +180,13 @@ impl<TFileSystem: Clone + Debug + Default + FileSystem>
return result;
}

if let Some(ref mut non_empty_dir_delete_modal) = self.non_empty_dir_delete_modal {
let result = non_empty_dir_delete_modal.handle_event(event, store);
self.map_state(store);

return result;
}

if let Some(ref mut create_modal) = self.create_modal {
let result = create_modal.handle_event(event, store);
self.map_state(store);
Expand Down Expand Up @@ -233,6 +265,28 @@ impl<TFileSystem: Clone + Debug + Default + FileSystem>
}
}

if let Some(ref non_empty_dir_delete_modal) = self.non_empty_dir_delete_modal {
if let Some(focused_panel) = local_state.focused_panel.clone() {
match focused_panel {
PanelSide::Left => non_empty_dir_delete_modal.render(frame, Some(layout[0])),
PanelSide::Right => non_empty_dir_delete_modal.render(frame, Some(layout[1])),
};
} else {
non_empty_dir_delete_modal.render(frame, None);
}
}

if let Some(ref error_modal) = self.error_modal {
if let Some(focused_panel) = local_state.focused_panel.clone() {
match focused_panel {
PanelSide::Left => error_modal.render(frame, Some(layout[0])),
PanelSide::Right => error_modal.render(frame, Some(layout[1])),
};
} else {
error_modal.render(frame, None);
}
}

if let Some(ref error_modal) = self.error_modal {
if let Some(focused_panel) = local_state.focused_panel.clone() {
match focused_panel {
Expand Down
1 change: 1 addition & 0 deletions src/app/components/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ impl<TFileSystem: Clone + Debug + Default + FileSystem>
tab: tab_idx,
side: tab_side.clone(),
},
is_empty: dir.is_empty(),
},
));
}
Expand Down
Loading

0 comments on commit f19686f

Please sign in to comment.