Implement saving for edited files

This commit is contained in:
Patrick Auernig 2023-08-17 21:52:01 +02:00
parent db431c5d6c
commit 26e696693f
4 changed files with 64 additions and 21 deletions

View File

@ -69,6 +69,8 @@ pub enum Message {
MoveSection(Direction),
MoveCur(Direction),
SaveFile,
}
@ -189,6 +191,15 @@ fn handle_message(
state.show_error_message(err);
}
}
Message::SaveFile => {
info!("Saving file");
if let Err(err) = state.save_edited_file() {
state.show_error_message(err);
}
state.prompt_save = false;
msg_tx.send(Message::SetMode(Mode::Normal))?;
}
_ => (),
}

View File

@ -58,7 +58,11 @@ fn handle_keyboard_input(
}
(Mode::SelectFile, KeyCode::Enter) => {
msg_tx.send(Message::LoadFile)?;
if state.prompt_save {
msg_tx.send(Message::SaveFile)?;
} else {
msg_tx.send(Message::LoadFile)?;
}
}
(Mode::SelectFile, _) => {
@ -121,6 +125,12 @@ fn handle_keyboard_input(
msg_tx.send(Message::PreviousEntryValue)?;
}
(Mode::Edit, KeyCode::Char('s')) => {
state.prompt_save = true;
state.file_select = Input::default();
msg_tx.send(Message::SetMode(Mode::SelectFile))?;
}
(Mode::Insert, KeyCode::Enter) => {
msg_tx.send(Message::CommitEditEntry)?;
}

View File

@ -1,5 +1,5 @@
use core::fmt;
use std::fs::{self, create_dir_all, read_to_string};
use std::fs::{self, create_dir_all, read_to_string, OpenOptions};
use std::io::Write;
use std::os::unix::prelude::OsStrExt;
use std::path::Path;
@ -52,13 +52,14 @@ pub enum Section {
#[derive(Default)]
pub struct State {
pub savefile: Option<Savefile>,
original_file: Option<Savefile>,
pub original_file: Option<Savefile>,
pub active_section: Section,
pub stats_table: TableState,
pub glyphs_table: TableState,
pub murals_table: TableState,
pub error_msg: Option<(Instant, String)>,
pub mode: Mode,
pub prompt_save: bool,
pub edit_input: Option<Input>,
pub file_select: Input,
#[cfg(feature = "watch")]
@ -69,6 +70,21 @@ pub struct State {
impl State {
const ERROR_MSG_DURATION: Duration = Duration::new(3, 0);
pub fn load() -> Result<Self> {
let data_dir = DIRS.data_local_dir();
if !data_dir.exists() {
create_dir_all(&data_dir)?;
}
let savefile = load_last_active_savefile()?;
Ok(Self {
savefile,
..Default::default()
})
}
pub fn show_error_message<S>(&mut self, msg: S)
where
S: fmt::Display,
@ -90,21 +106,6 @@ impl State {
self.error_msg.take();
}
pub fn load() -> Result<Self> {
let data_dir = DIRS.data_local_dir();
if !data_dir.exists() {
create_dir_all(&data_dir)?;
}
let savefile = load_last_active_savefile()?;
Ok(Self {
savefile,
..Default::default()
})
}
pub fn set_savefile_from_path<P>(&mut self, path: P) -> Result<()>
where
P: AsRef<Path>,
@ -290,6 +291,22 @@ impl State {
Ok(())
}
pub fn save_edited_file(&mut self) -> Result<()> {
let path = self.file_select.value();
let savefile = self.savefile.as_ref().context("no active savefile")?;
let outfile = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)?;
savefile.write(outfile)?;
Ok(())
}
pub fn move_section(&mut self, direction: Direction) {
let next_section = match (direction, self.active_section) {
(Direction::Left, Section::Companions) => Section::General,

View File

@ -54,16 +54,21 @@ pub fn render_status(state: &State, mut frame: &mut Frame, block: Block, area: R
}
fn render_file_select(state: &State, frame: &mut Frame, block: Block, area: Rect) {
const PROMPT: &str = "Open file:";
const PADDING: usize = 2;
let prompt = if state.prompt_save {
"Save as:"
} else {
"Open file:"
};
let scroll = state.file_select.visual_scroll(area.width as usize);
let input = Paragraph::new(format!("{} {}", PROMPT, state.file_select.value()))
let input = Paragraph::new(format!("{} {}", prompt, state.file_select.value()))
.scroll((0, scroll as u16))
.block(block);
frame.render_widget(input, area);
frame.set_cursor(
area.x + (state.file_select.visual_cursor() + PROMPT.len() + 1 + PADDING) as u16,
area.x + (state.file_select.visual_cursor() + prompt.len() + 1 + PADDING) as u16,
area.y,
);
}