create new page
This commit is contained in:
73
src/main.rs
73
src/main.rs
@@ -16,8 +16,8 @@ use tui_textarea::TextArea;
|
||||
use tracing::info;
|
||||
use tracing_subscriber::fmt;
|
||||
|
||||
use api::{do_login, fetch_page_content, fetch_pages, fetch_spaces, save_page, search_pages};
|
||||
use app::{App, AppMsg, AppState, EditorFocus, EditorStatus, EditorView, LoginField, Panel, SearchView};
|
||||
use api::{create_page, do_login, fetch_page_content, fetch_pages, fetch_spaces, save_page, search_pages};
|
||||
use app::{App, AppMsg, AppState, EditorFocus, EditorStatus, EditorView, LoginField, NewPageDialog, Panel, SearchView};
|
||||
use ui::{draw_editor, draw_login, draw_main, draw_search};
|
||||
|
||||
// ─── Entry point ──────────────────────────────────────────────────────────────
|
||||
@@ -144,6 +144,30 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
app.editor.saving = false;
|
||||
app.editor.status = Some(EditorStatus::Error(e));
|
||||
}
|
||||
AppMsg::PageCreated { page_id, title } => {
|
||||
info!("page created: id={page_id} title={title:?}");
|
||||
app.main.new_page_dialog = None;
|
||||
// Refresh pages list then open the new page in the editor
|
||||
spawn_fetch_pages(&app, &tx);
|
||||
app.main.loading_page_content = true;
|
||||
let base_url = app.base_url.clone();
|
||||
let token = app.token.clone();
|
||||
let tx2 = tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let msg = match fetch_page_content(&base_url, &token, &page_id).await {
|
||||
Ok(content) => AppMsg::PageContentLoaded { page_id, title, content },
|
||||
Err(e) => AppMsg::ApiError(e),
|
||||
};
|
||||
let _ = tx2.send(msg);
|
||||
});
|
||||
}
|
||||
AppMsg::CreateError(e) => {
|
||||
info!("create error: {e}");
|
||||
if let Some(d) = app.main.new_page_dialog.as_mut() {
|
||||
d.creating = false;
|
||||
d.error = Some(e);
|
||||
}
|
||||
}
|
||||
AppMsg::SearchResults(results) => {
|
||||
info!("search results: {} items", results.len());
|
||||
app.search.loading = false;
|
||||
@@ -255,6 +279,45 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
if app.main.loading_page_content {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ── New-page dialog intercepts all keys when open ──
|
||||
if let Some(dialog) = app.main.new_page_dialog.as_mut() {
|
||||
if dialog.creating { continue; }
|
||||
match key.code {
|
||||
KeyCode::Esc => { app.main.new_page_dialog = None; }
|
||||
KeyCode::Backspace => { dialog.title.pop(); }
|
||||
KeyCode::Enter => {
|
||||
if dialog.title.trim().is_empty() {
|
||||
dialog.error = Some("Title cannot be empty.".into());
|
||||
} else {
|
||||
dialog.creating = true;
|
||||
dialog.error = None;
|
||||
let base_url = app.base_url.clone();
|
||||
let token = app.token.clone();
|
||||
let title = dialog.title.trim().to_string();
|
||||
let space_id = app.main.spaces
|
||||
.get(app.main.selected_space)
|
||||
.map(|s| s.id.clone())
|
||||
.unwrap_or_default();
|
||||
let tx2 = tx.clone();
|
||||
tokio::spawn(async move {
|
||||
let msg = match create_page(&base_url, &token, &space_id, &title).await {
|
||||
Ok((page_id, title)) => AppMsg::PageCreated { page_id, title },
|
||||
Err(e) => AppMsg::CreateError(e),
|
||||
};
|
||||
let _ = tx2.send(msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
KeyCode::Char(c) if !key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
dialog.error = None;
|
||||
dialog.title.push(c);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
match key.code {
|
||||
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
|
||||
KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
@@ -292,6 +355,12 @@ async fn run_app(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> io::R
|
||||
}
|
||||
}
|
||||
},
|
||||
// n → new page in current space
|
||||
KeyCode::Char('n') => {
|
||||
if !app.main.spaces.is_empty() {
|
||||
app.main.new_page_dialog = Some(NewPageDialog::new());
|
||||
}
|
||||
}
|
||||
// / or Ctrl+F → open search
|
||||
KeyCode::Char('/') | KeyCode::Char('f')
|
||||
if key.code == KeyCode::Char('/')
|
||||
|
||||
Reference in New Issue
Block a user