Skip to content

Commit

Permalink
wip: recent flakes (still on sqlite)
Browse files Browse the repository at this point in the history
  • Loading branch information
srid committed Nov 1, 2023
1 parent cc4b5a9 commit dafeafb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
11 changes: 7 additions & 4 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod widget;

use dioxus::prelude::*;
use dioxus_router::prelude::*;
use dioxus_signals::Signal;
use nix_rs::flake::url::FlakeUrl;

use crate::app::{
Expand Down Expand Up @@ -157,13 +158,15 @@ fn Footer(cx: Scope) -> Element {
// Home page
fn Dashboard(cx: Scope) -> Element {
tracing::debug!("Rendering Dashboard page");
// TODO: Store and show user's recent flake visits
let suggestions = FlakeUrl::suggestions();
let state = AppState::use_state(cx);
render! {
div { class: "pl-4",
h2 { class: "text-2xl", "We have hand-picked some flakes for you to try out:" }
h2 { class: "text-2xl", "Enter a flake URL:" }
// TODO: search input here
p { "TODO: search input" }
h2 { class: "text-2xl", "Or, try one of these:" }
div { class: "flex flex-col",
for flake in suggestions {
for flake in state.recent_flakes.read().clone() {
a {
onclick: move |_| {
let state = AppState::use_state(cx);
Expand Down
37 changes: 35 additions & 2 deletions src/app/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ pub struct AppState {
pub nix_info: Signal<Datum<Result<nix_rs::info::NixInfo, SystemError>>>,
pub health_checks: Signal<Datum<Result<Vec<nix_health::traits::Check>, SystemError>>>,

/// User selected [FlakeUrl]
pub flake_url: Signal<Option<FlakeUrl>>,
/// [Flake] for [AppState::flake_url]
pub flake: Signal<Datum<Result<Flake, NixCmdError>>>,
/// List of recently selected [AppState::flake_url]s
pub recent_flakes: Signal<Vec<FlakeUrl>>,

/// [Action] represents the next modification to perform on [AppState] signals
pub action: Signal<(usize, Action)>,
Expand Down Expand Up @@ -96,13 +100,19 @@ impl AppState {
state.build_network(cx);
use_future(cx, (), |_| async move {
// XXX: Simulating slowness
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
// tokio::time::sleep(std::time::Duration::from_secs(2)).await;
state.initialize().await;
});
}

async fn initialize(self) {
let db = Db::new().await;

if let Ok(db) = db.as_ref() {
self.recent_flakes
.set(db.recent_flakes().await.unwrap_or_default());
}

self.db.set(Some(db));
}

Expand All @@ -117,7 +127,7 @@ impl AppState {
}

/// Get [Db]. Only safe after initialization (see [AppState::initialization_state]])
fn get_db(self) -> Db {
pub(crate) fn get_db(self) -> Db {
self.db.read().as_ref().unwrap().as_ref().unwrap().clone()
}

Expand All @@ -140,6 +150,15 @@ impl AppState {
// TODO: refactor?
if let Err(err) = self.get_db().register_flake(&flake_url).await {
tracing::error!("Failed to register flake in db: {}", err);
} else {
match self.get_db().recent_flakes().await {
Ok(recent_flakes) => {
self.recent_flakes.set(recent_flakes);
}
Err(err) => {
tracing::error!("Failed to get recent flakes: {}", err);
}
}
}
Datum::refresh_with(self.flake, async move {
Flake::from_nix(&nix_rs::command::NixCmd::default(), flake_url.clone())
Expand All @@ -150,6 +169,20 @@ impl AppState {
});
}

// Update recent flakes
{
let flake_url = self.flake_url.read().clone();
use_future(cx, (&flake_url,), |(flake_url,)| async move {
if let Some(flake_url) = flake_url {
let mut recent_flakes = self.recent_flakes.read().clone();
if !recent_flakes.contains(&flake_url) {
recent_flakes.push(flake_url.clone());
self.recent_flakes.set(recent_flakes);
}
}
});
}

// Build `state.health_checks` when nix_info changes
{
let nix_info = self.nix_info.read().clone();
Expand Down
15 changes: 13 additions & 2 deletions src/app/state/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ impl Db {
.foreign_keys(true)
// TODO: Use ProjectDirs
.filename("nix-browser.db");
// FIXME: Handle error and display in UI!
let pool = SqlitePool::connect_with(db_opts).await?;

// Initial schema
sqlx::query(
"CREATE TABLE IF NOT EXISTS flake (
url TEXT NOT NULL,
url TEXT NOT NULL PRIMARY KEY,
metadata JSON,
last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_fetched TIMESTAMP
Expand All @@ -41,4 +40,16 @@ impl Db {
.await?;
Ok(())
}

pub async fn recent_flakes(&self) -> Result<Vec<FlakeUrl>, sqlx::Error> {
let mut rows: Vec<(String,)> =
sqlx::query_as("SELECT url FROM flake ORDER BY last_accessed ASC LIMIT 10")
.fetch_all(&self.pool)
.await?;
let mut urls = Vec::new();
while let Some(row) = rows.pop() {
urls.push(row.0.into());
}
Ok(urls)
}
}

0 comments on commit dafeafb

Please sign in to comment.