title editor
This commit is contained in:
42
src/main.rs
42
src/main.rs
@@ -17,7 +17,7 @@ use tracing::info;
|
||||
use tracing_subscriber::fmt;
|
||||
|
||||
use api::{do_login, fetch_page_content, fetch_pages, fetch_spaces, save_page};
|
||||
use app::{App, AppMsg, AppState, EditorStatus, EditorView, LoginField, Panel};
|
||||
use app::{App, AppMsg, AppState, EditorFocus, EditorStatus, EditorView, LoginField, Panel};
|
||||
use ui::{draw_editor, draw_login, draw_main};
|
||||
|
||||
// ─── Entry point ──────────────────────────────────────────────────────────────
|
||||
@@ -129,6 +129,14 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
info!("page saved ok");
|
||||
app.editor.saving = false;
|
||||
app.editor.status = Some(EditorStatus::Saved);
|
||||
// Update the title in the pages list immediately
|
||||
let saved_id = app.editor.page_id.clone();
|
||||
let saved_title = app.editor.page_title.clone();
|
||||
if let Some(page) = app.main.pages.iter_mut().find(|p| p.id == saved_id) {
|
||||
page.title = Some(saved_title);
|
||||
}
|
||||
// Refresh pages from server in the background
|
||||
spawn_fetch_pages(&app, &tx);
|
||||
}
|
||||
AppMsg::SaveError(e) => {
|
||||
info!("save error: {e}");
|
||||
@@ -274,7 +282,7 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
|
||||
// ── Editor keys ───────────────────────────────────────────
|
||||
AppState::Editor => {
|
||||
// Clear status on any keypress
|
||||
// Clear "Saved!" status on any keypress
|
||||
if matches!(app.editor.status, Some(EditorStatus::Saved)) {
|
||||
app.editor.status = None;
|
||||
}
|
||||
@@ -285,7 +293,7 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
app.state = AppState::Main;
|
||||
editor_textarea = None;
|
||||
}
|
||||
// Ctrl+S → save
|
||||
// Ctrl+S → save both title and content
|
||||
(KeyCode::Char('s'), m) if m.contains(KeyModifiers::CONTROL) => {
|
||||
if !app.editor.saving {
|
||||
app.editor.saving = true;
|
||||
@@ -293,13 +301,14 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
let base_url = app.base_url.clone();
|
||||
let token = app.token.clone();
|
||||
let page_id = app.editor.page_id.clone();
|
||||
let title = app.editor.page_title.clone();
|
||||
let content = editor_textarea
|
||||
.as_ref()
|
||||
.map(|ta| ta.lines().join("\n"))
|
||||
.unwrap_or_default();
|
||||
let tx2 = tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let msg = match save_page(&base_url, &token, &page_id, &content).await {
|
||||
let msg = match save_page(&base_url, &token, &page_id, &title, &content).await {
|
||||
Ok(()) => AppMsg::PageSaved,
|
||||
Err(e) => AppMsg::SaveError(e),
|
||||
};
|
||||
@@ -307,10 +316,29 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
});
|
||||
}
|
||||
}
|
||||
// All other keys → delegate to textarea
|
||||
// Tab → toggle focus between title and content
|
||||
(KeyCode::Tab, _) => {
|
||||
app.editor.focus = match app.editor.focus {
|
||||
EditorFocus::Title => EditorFocus::Content,
|
||||
EditorFocus::Content => EditorFocus::Title,
|
||||
};
|
||||
}
|
||||
// Title field keys
|
||||
(KeyCode::Backspace, _) if app.editor.focus == EditorFocus::Title => {
|
||||
app.editor.page_title.pop();
|
||||
}
|
||||
(KeyCode::Char(c), m)
|
||||
if app.editor.focus == EditorFocus::Title
|
||||
&& !m.contains(KeyModifiers::CONTROL) =>
|
||||
{
|
||||
app.editor.page_title.push(c);
|
||||
}
|
||||
// All other keys → delegate to content textarea
|
||||
_ => {
|
||||
if let Some(ta) = editor_textarea.as_mut() {
|
||||
ta.input(key);
|
||||
if app.editor.focus == EditorFocus::Content {
|
||||
if let Some(ta) = editor_textarea.as_mut() {
|
||||
ta.input(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user