⎇ e2da24239e1e1fe440aa4497e734b9fa8b3457eb
crates/apps/tahuantinsuyu/src/main.rs
History
Who touched what
raw
feat(tahuantinsuyu): fase 26 — data plane brahman real (service socket + CLI)
1//! Tahuantinsuyu — binario standalone.
2//!
3//! Boot:
4//! 1. `tahuantinsuyu_card::spawn_sidecar()` se presenta al Init brahman
5//! (fire-and-forget; si no hay Init, la app sigue standalone).
6//! 2. Abre la DB SQLite en `$XDG_DATA_HOME/tahuantinsuyu/charts.db`
7//! (fallback a `~/.local/share/tahuantinsuyu/charts.db`).
8//! 3. Levanta GPUI con [`yahweh_theme::Theme::install_default`].
9//! 4. Compone el shell: [`Shell`] dueño del tree (izq), canvas (centro)
10//! y panel (abajo). Cablea las suscripciones cross-widget.
11//!
12//! ## Layout
13//!
14//! ```text
15//! ┌───────────┬────────────────────────────────────────┐
16//! │ │ │
17//! │ tree │ canvas │
18//! │ (groups, │ (rueda / thumbnails) │
19//! │ contacts,│ │
20//! │ charts) │ │
21//! │ │ │
22//! ├───────────┴────────────────────────────────────────┤
23//! │ control panel (módulos) │
24//! └─────────────────────────────────────────────────────┘
25//! ```
26
27mod shell;
28
29use std::path::PathBuf;
30
31use gpui::{
32 App, AppContext, Application, Bounds, SharedString, TitlebarOptions, WindowBounds,
33 WindowOptions, px, size,
34};
35
36use tahuantinsuyu_store::Store;
37use yahweh_theme::Theme;
38
39use crate::shell::Shell;
40
41const DB_FILENAME: &str = "charts.db";
42const APP_TITLE: &str = "Tahuantinsuyu";
43
44fn main() {
45 // Sidecar brahman primero — si el Init está corriendo, nos presentamos.
46 tahuantinsuyu_card::spawn_sidecar();
47 // Service socket: thread separado escuchando ComputeRequest. Otros
48 // módulos brahman pueden conectar y pedir cómputos de cartas
49 // natales sin GUI. Si el bind falla (socket ya tomado, sin
50 // permisos), loggea warn y la app sigue corriendo standalone.
51 let service_socket = tahuantinsuyu_card::service::default_service_socket();
52 eprintln!("[tahuantinsuyu] service socket → {}", service_socket.display());
53 tahuantinsuyu_card::service::spawn_service_thread(service_socket);
54
55 // DB en directorio de datos del usuario.
56 let db_path = resolve_db_path();
57 let store = match Store::open(&db_path) {
58 Ok(s) => s,
59 Err(e) => {
60 eprintln!(
61 "[tahuantinsuyu] no se pudo abrir la DB en {:?}: {} — usando memoria",
62 db_path, e
63 );
64 Store::in_memory().expect("in-memory store")
65 }
66 };
67
68 Application::new().run(move |cx: &mut App| {
69 Theme::install_default(cx);
70
71 let bounds = Bounds::centered(None, size(px(1400.0), px(900.0)), cx);
72 cx.open_window(
73 WindowOptions {
74 window_bounds: Some(WindowBounds::Windowed(bounds)),
75 titlebar: Some(TitlebarOptions {
76 title: Some(SharedString::from(APP_TITLE)),
77 ..Default::default()
78 }),
79 ..Default::default()
80 },
81 move |_w, cx| cx.new(|cx| Shell::new(store.clone(), cx)),
82 )
83 .expect("open window");
84 cx.activate(true);
85 });
86}
87
88fn resolve_db_path() -> PathBuf {
89 if let Some(dirs) = directories::ProjectDirs::from("net", "gioser", "tahuantinsuyu") {
90 let dir = dirs.data_dir().to_path_buf();
91 let _ = std::fs::create_dir_all(&dir);
92 return dir.join(DB_FILENAME);
93 }
94 PathBuf::from(DB_FILENAME)
95}