Files
Marcos Paulo 15d7f5e873 feat: editor blocks and lint, vault knowledge, calendar plugin, macOS menu
- notescraft-lint (rules, safe fixes, learned style) and notescraft-blocks (block model and edits); engine lint.* and block.* commands with CLI and MCP parity
- Lint tab, underlines, slash menu with preview in Source and Visual, block grip and menu, Settings > Editor and lint, Vim block keys
- Visual view: tables, note embeds, %% comments, wrapping property chips
- Vault knowledge (Related tab, assistant sources, Settings) and calendar plugin
- Sidebar top padding fixed, dot grid follows PaperCraft spacing, right-card tabs no longer cover the collapse button

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 12:36:00 -03:00

93 lines
3.8 KiB
Rust

//! Renders the settings view offscreen for visual inspection.
use notescraft_engine::{AppSettings, Connection, ConnectionKind};
use notescraft_ui_egui::{
settings_view::{self, SettingsCategory, SettingsView, ThemeInfo},
text::settings_view_categories as strings,
theme::Tokens,
};
struct SettingsExample {
tokens: Tokens,
view: SettingsView,
settings: AppSettings,
themes: Vec<ThemeInfo>,
fonts_ready: bool,
}
fn main() {
let Some(theme) = notescraft_themes::builtin("catppuccin-mocha") else {
eprintln!("missing built-in theme");
return;
};
let themes: Vec<ThemeInfo> = notescraft_themes::builtin_ids().iter().filter_map(|id| notescraft_themes::builtin(id)).map(ThemeInfo::from_theme).collect();
let mut view = SettingsView::default();
view.selected = SettingsCategory::AiAssistant;
let args: Vec<String> = std::env::args().collect();
let arg = |name: &str| args.iter().position(|a| a == name).and_then(|i| args.get(i + 1).cloned());
if args.iter().any(|a| a == "--knowledge-demo") {
view.knowledge =
Some(settings_view::knowledge_data::KnowledgeStatus { notes: 214, passages: 1842, built_at: Some(998), now: 1000, last_search_ms: Some(4) });
}
if args.iter().any(|a| a == "--editor") {
view.selected = SettingsCategory::Editor;
}
let mut settings = if std::env::args().any(|argument| argument == "--connections-demo") { demo_settings() } else { AppSettings::default() };
if args.iter().any(|a| a == "--knowledge-demo") {
settings.session.knowledge.excluded = vec!["Private".to_owned(), "Journal/2019".to_owned()];
}
let size = arg("--size")
.and_then(|s| s.split_once('x').and_then(|(w, h)| Some(egui::vec2(w.parse().ok()?, h.parse().ok()?))))
.unwrap_or(egui::vec2(1440.0, 900.0));
let out = arg("--out").unwrap_or_else(|| "/tmp/notescraft-settings-view.png".to_owned());
let app = SettingsExample { tokens: Tokens::new(theme), view, settings, themes, fonts_ready: false };
let mut harness = egui_kittest::Harness::builder().with_size(size).with_pixels_per_point(1.0).with_max_steps(32).wgpu().build_ui_state(
|ui, state: &mut SettingsExample| {
if !state.fonts_ready {
egui_extras::install_image_loaders(ui.ctx());
notescraft_ui_egui::fonts::install(ui.ctx());
notescraft_ui_egui::style::apply(ui.ctx(), &state.tokens);
state.fonts_ready = true;
ui.ctx().request_repaint();
return;
}
let _ = settings_view::show_settings(ui, &state.tokens, &mut state.view, &state.settings, &state.themes);
},
app,
);
harness.run();
match harness.render() {
Ok(image) => {
if let Err(error) = image.save(&out) {
eprintln!("could not save settings screenshot: {error}");
}
}
Err(error) => eprintln!("could not render settings screenshot: {error}"),
}
}
fn demo_settings() -> AppSettings {
let mut settings = AppSettings::default();
settings.assistant.connections = vec![
Connection {
id: "codex".to_owned(),
name: strings::codex().to_owned(),
command: "codex-acp".to_owned(),
icon: "codex".to_owned(),
..Connection::default()
},
Connection {
id: "openai".to_owned(),
name: strings::openai().to_owned(),
kind: ConnectionKind::Openai,
base_url: "https://api.openai.com/v1".to_owned(),
model: "gpt-4.1-mini".to_owned(),
api_key_env: "OPENAI_API_KEY".to_owned(),
icon: "openai".to_owned(),
..Connection::default()
},
];
"codex".clone_into(&mut settings.assistant.active);
settings
}