use gpui::{bounds, point, prelude::*, px, size}; use crate::{query::fetch_query, screen::dashboard, screen::setup_wizard}; mod api; mod app; mod asset; mod colors; mod component; mod http; mod query; mod screen; mod storage; mod theme; mod util; enum Start { FromScratch, FromSetup(setup_wizard::StoredSetupState), FromSaved(storage::PersistedState), } fn main() { // GPUI polls our async query futures, but reqwest relies on Tokio's // reactor and blocking pool for DNS, sockets, and timers. let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .expect("failed to build Tokio runtime"); let _runtime_guard = runtime.enter(); gpui::Application::new() .with_assets(asset::Asset) .with_http_client(std::sync::Arc::new(http::Client::new( reqwest::Client::new(), ))) .run(setup_application); } fn setup_application(cx: &mut gpui::App) { let query_store = query::Store::new(api::QueryContext { http: reqwest::Client::new(), auth: None, github: api::GithubCredentials { base_url: "https://api.github.com", client_id: "Iv23liZD4bMQpGJICsR7", }, }); let theme_family = theme::ThemeFamily::default(); let global = app::Global { safe_area: bounds(point(px(0.), px(0.)), size(px(72.), px(12.))), theme_family, current_theme: theme_family.theme_for_appearance(cx.window_appearance()), rng: rand::rng(), }; cx.set_global(global); cx.set_global(query_store); // TODO: handle failure _ = storage::ensure_data_dir(); let start = resume_application_state(cx); match start { Start::FromScratch => { let screen = setup_wizard::new(); _ = setup_wizard::open_window(screen, cx); } Start::FromSetup(state) => { let screen = setup_wizard::from_saved(state); _ = setup_wizard::open_window(screen, cx); } Start::FromSaved(_) => { let screen = dashboard::new(cx); _ = dashboard::open_window(screen, cx); } }; } fn resume_application_state(cx: &mut gpui::App) -> Start { let state = storage::load_persisted_state(); let Some(mut state) = state else { return Start::FromScratch; }; let auth_tokens = if cfg!(debug_assertions) { state.debug_auth_tokens.take() } else { cx.background_executor() .block(storage::load_auth_tokens(cx, state.selected_account)) }; let Some(auth_tokens) = auth_tokens else { return Start::FromScratch; }; _ = cx.update_global::, _>(|store, _| { store.update_query_context(|cx| { cx.auth = Some(auth_tokens); }); }); let setup_status = setup_wizard::read_setup_status(); println!("[main] setup status: {:?}", setup_status); match setup_status { setup_wizard::SetupStatus::NotStarted => Start::FromScratch, setup_wizard::SetupStatus::InProgress(state) => Start::FromSetup(state), setup_wizard::SetupStatus::Completed => Start::FromSaved(state), } }