From c310668a11bef8a095160db82045bc245a97b464 Mon Sep 17 00:00:00 2001 From: Victor Fuentes Date: Tue, 29 Nov 2022 02:11:29 -0500 Subject: [PATCH] Add better offline support --- Cargo.lock | 22 ++--- data/icons/nsc-network-offline-symbolic.svg | 7 ++ data/icons/nsc-refresh-symbolic.svg | 2 + data/resources/resources.gresource.xml | 8 +- default.nix | 2 +- src/parse/mod.rs | 3 +- src/parse/util.rs | 3 + src/ui/pkgpage.rs | 62 +++++++++++++ src/ui/updatepage.rs | 49 +++++++++- src/ui/window.rs | 99 ++++++++++++++++----- src/ui/windowloading.rs | 53 ++++++++++- 11 files changed, 270 insertions(+), 40 deletions(-) create mode 100644 data/icons/nsc-network-offline-symbolic.svg create mode 100644 data/icons/nsc-refresh-symbolic.svg create mode 100644 src/parse/util.rs diff --git a/Cargo.lock b/Cargo.lock index 9044ac3..c3dfa5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -795,9 +795,9 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba3e42776d1466938add08211734738d5c76e863a25b7a8064c4433a74a1a26" +checksum = "d3094f2b8578136d1929cade4e0fff82f573521b579e96cfc24af2458431f176" dependencies = [ "bitflags", "gdk-pixbuf-sys", @@ -920,9 +920,9 @@ dependencies = [ [[package]] name = "glib" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50feee2f1e73be50e6634c901bfced69a0937c5e4e4673067ade85e093fa9bd7" +checksum = "d5204a4217749b385cefbfb7bf3a2fcde83e4ce6d0945f64440a1f5bd4010305" dependencies = [ "bitflags", "futures-channel", @@ -1375,9 +1375,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e394faa0efb47f9f227f1cd89978f854542b318a6f64fa695489c9c993056656" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" dependencies = [ "libc", "windows-sys 0.42.0", @@ -1391,9 +1391,9 @@ checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" [[package]] name = "is-terminal" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae5bc6e2eb41c9def29a3e0f1306382807764b9b53112030eff57435667352d" +checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" dependencies = [ "hermit-abi 0.2.6", "io-lifetimes", @@ -1675,7 +1675,7 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] name = "nix-data" version = "0.0.2" -source = "git+https://github.com/snowflakelinux/nix-data#42d0e42536627cdce50c522f161617b797f670be" +source = "git+https://github.com/snowflakelinux/nix-data#4ddd91d514b6ce3286033398277d25a1a1a456dc" dependencies = [ "anyhow", "brotli", @@ -2369,9 +2369,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e" +checksum = "cb93e85278e08bb5788653183213d3a60fc242b10cb9be96586f5a73dcb67c23" dependencies = [ "bitflags", "errno", diff --git a/data/icons/nsc-network-offline-symbolic.svg b/data/icons/nsc-network-offline-symbolic.svg new file mode 100644 index 0000000..2320c68 --- /dev/null +++ b/data/icons/nsc-network-offline-symbolic.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/data/icons/nsc-refresh-symbolic.svg b/data/icons/nsc-refresh-symbolic.svg new file mode 100644 index 0000000..fd5998f --- /dev/null +++ b/data/icons/nsc-refresh-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml index 6fb68ca..42f75f7 100644 --- a/data/resources/resources.gresource.xml +++ b/data/resources/resources.gresource.xml @@ -1,13 +1,15 @@ - ../icons/nsc-home-symbolic.svg - ../icons/nsc-installed-symbolic.svg - ../icons/nsc-update-symbolic.svg ../icons/nsc-audio.svg ../icons/nsc-development.svg ../icons/nsc-gaming.svg ../icons/nsc-graphics.svg + ../icons/nsc-home-symbolic.svg + ../icons/nsc-installed-symbolic.svg + ../icons/nsc-network-offline-symbolic.svg + ../icons/nsc-refresh-symbolic.svg + ../icons/nsc-update-symbolic.svg ../icons/nsc-video.svg ../icons/nsc-web.svg diff --git a/default.nix b/default.nix index 2063838..d7769c2 100644 --- a/default.nix +++ b/default.nix @@ -20,7 +20,7 @@ pkgs.stdenv.mkDerivation rec { cargoDeps = pkgs.rustPlatform.fetchCargoTarball { inherit src; name = "${pname}-${version}"; - hash = "sha256-OmHjQkK1MGes9hbJ0LEGdP1wA8ohAJEon0ycoNppl0E="; + hash = "sha256-6iFIyW2wH4EQn5C4+35N63wylL8DSU9YWbe8NUMMnDA="; }; nativeBuildInputs = with pkgs; [ diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 03e6d1b..7934978 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -1,2 +1,3 @@ pub mod packages; -pub mod config; \ No newline at end of file +pub mod config; +pub mod util; \ No newline at end of file diff --git a/src/parse/util.rs b/src/parse/util.rs new file mode 100644 index 0000000..410c842 --- /dev/null +++ b/src/parse/util.rs @@ -0,0 +1,3 @@ +pub fn checkonline() -> bool { + reqwest::blocking::get("https://nmcheck.gnome.org/check_network_status.txt").is_ok() +} \ No newline at end of file diff --git a/src/ui/pkgpage.rs b/src/ui/pkgpage.rs index 555c2c5..16d1e2e 100644 --- a/src/ui/pkgpage.rs +++ b/src/ui/pkgpage.rs @@ -24,6 +24,7 @@ use std::{ use log::*; use crate::parse::packages::PkgMaintainer; +use crate::parse::util; use crate::ui::installworker::InstallAsyncHandlerMsg; use super::installworker::InstallAsyncHandler; @@ -63,6 +64,7 @@ pub struct PkgModel { workqueue: HashSet, visible: bool, + online: bool, } #[derive(Debug, Hash, Eq, PartialEq, Clone)] @@ -156,6 +158,7 @@ pub enum PkgMsg { NixShell, SetInstallType(InstallType), AddToQueue(WorkPkg), + UpdateOnline(bool) } #[derive(Debug)] @@ -169,6 +172,7 @@ pub struct PkgPageInit { pub syspkgs: SystemPkgs, pub userpkgs: UserPkgs, pub config: NixDataConfig, + pub online: bool } #[relm4::component(pub)] @@ -353,6 +357,27 @@ impl Component for PkgModel { // set_sensitive: false, // } // } + } else if !model.online { + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + set_halign: gtk::Align::End, + gtk::Button { + set_halign: gtk::Align::End, + set_valign: gtk::Align::Center, + add_css_class: "error", + set_label: "Offline", + set_can_target: false, + }, + gtk::Button { + set_halign: gtk::Align::End, + set_valign: gtk::Align::Center, + set_icon_name: "nsc-refresh-symbolic", + connect_clicked[sender] => move |_| { + sender.output(AppMsg::CheckNetwork); + } + } + } } else { adw::SplitButton { add_css_class: "suggested-action", @@ -439,6 +464,27 @@ impl Component for PkgModel { // set_sensitive: false, // } // } + } else if !model.online { + gtk::Box { + set_orientation: gtk::Orientation::Horizontal, + set_spacing: 10, + set_halign: gtk::Align::End, + gtk::Button { + set_halign: gtk::Align::End, + set_valign: gtk::Align::Center, + add_css_class: "error", + set_label: "Offline", + set_can_target: false, + }, + gtk::Button { + set_halign: gtk::Align::End, + set_valign: gtk::Align::Center, + set_icon_name: "nsc-refresh-symbolic", + connect_clicked[sender] => move |_| { + sender.output(AppMsg::CheckNetwork); + } + } + } } else { adw::SplitButton { add_css_class: "suggested-action", @@ -965,6 +1011,7 @@ impl Component for PkgModel { workqueue: HashSet::new(), launchable: None, visible: false, + online: initparams.online, tracker: 0, }; @@ -1285,6 +1332,12 @@ impl Component for PkgModel { sender.output(AppMsg::FrontPage); } PkgMsg::InstallUser => { + let online = util::checkonline(); + if !online { + sender.output(AppMsg::CheckNetwork); + self.online = false; + return; + } let w = WorkPkg { pkg: self.pkg.to_string(), pname: self.pname.to_string(), @@ -1313,6 +1366,12 @@ impl Component for PkgModel { } } PkgMsg::InstallSystem => { + let online = util::checkonline(); + if !online { + sender.output(AppMsg::CheckNetwork); + self.online = false; + return; + } let w = WorkPkg { pkg: self.pkg.to_string(), pname: self.pname.to_string(), @@ -1531,6 +1590,9 @@ impl Component for PkgModel { self.installworker.emit(InstallAsyncHandlerMsg::Process(work)); } } + PkgMsg::UpdateOnline(online) => { + self.set_online(online); + } } } diff --git a/src/ui/updatepage.rs b/src/ui/updatepage.rs index 4b75689..f839e78 100644 --- a/src/ui/updatepage.rs +++ b/src/ui/updatepage.rs @@ -1,4 +1,4 @@ -use crate::{APPINFO, ui::unavailabledialog::UnavailableDialogModel}; +use crate::{APPINFO, ui::unavailabledialog::UnavailableDialogModel, parse::util}; use super::{pkgpage::InstallType, window::*, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}, rebuild::RebuildMsg}; use adw::prelude::*; @@ -25,6 +25,7 @@ pub struct UpdatePageModel { updatetracker: u8, #[tracker::no_eq] unavailabledialog: Controller, + online: bool, } #[derive(Debug)] @@ -44,6 +45,7 @@ pub enum UpdatePageMsg { UpdateAllRm(Vec, Vec), DoneWorking, FailedWorking, + UpdateOnline(bool), } #[derive(Debug)] @@ -58,6 +60,7 @@ pub struct UpdatePageInit { pub systype: SystemPkgs, pub usertype: UserPkgs, pub config: NixDataConfig, + pub online: bool, } #[relm4::component(pub)] @@ -72,7 +75,25 @@ impl SimpleComponent for UpdatePageModel { #[track(model.changed(UpdatePageModel::updatetracker()))] set_vadjustment: gtk::Adjustment::NONE, adw::Clamp { - if model.channelupdate.is_some() || !model.updateuserlist.is_empty() || !model.updatesystemlist.is_empty() { + #[name(mainstack)] + if !model.online { + adw::StatusPage { + set_icon_name: Some("nsc-network-offline-symbolic"), + set_title: "No internet connection", + set_description: Some("Please connect to the internet to update your system"), + gtk::Button { + add_css_class: "pill", + set_halign: gtk::Align::Center, + adw::ButtonContent { + set_icon_name: "nsc-refresh-symbolic", + set_label: "Refresh", + }, + connect_clicked[sender] => move |_| { + sender.output(AppMsg::CheckNetwork); + } + } + } + } else if model.channelupdate.is_some() || !model.updateuserlist.is_empty() || !model.updatesystemlist.is_empty() { gtk::Box { set_orientation: gtk::Orientation::Vertical, set_valign: gtk::Align::Start, @@ -218,6 +239,7 @@ impl SimpleComponent for UpdatePageModel { systype: initparams.systype, usertype: initparams.usertype, unavailabledialog, + online: initparams.online, tracker: 0, }; @@ -225,6 +247,8 @@ impl SimpleComponent for UpdatePageModel { let updatesystemlist = model.updatesystemlist.widget(); let widgets = view_output!(); + widgets.mainstack.set_hhomogeneous(false); + widgets.mainstack.set_vhomogeneous(false); ComponentParts { model, widgets } } @@ -276,6 +300,12 @@ impl SimpleComponent for UpdatePageModel { } }, UpdatePageMsg::UpdateSystem => { + let online = util::checkonline(); + if !online { + sender.output(AppMsg::CheckNetwork); + self.online = false; + return; + } let systype = self.systype.clone(); let systemconfig = self.config.systemconfig.clone(); let workersender = self.updateworker.sender().clone(); @@ -308,6 +338,12 @@ impl SimpleComponent for UpdatePageModel { warn!("unimplemented"); } UpdatePageMsg::UpdateAllUser => { + let online = util::checkonline(); + if !online { + sender.output(AppMsg::CheckNetwork); + self.online = false; + return; + } REBUILD_BROKER.send(RebuildMsg::Show); if self.usertype == UserPkgs::Profile { let workersender = self.updateworker.sender().clone(); @@ -331,6 +367,12 @@ impl SimpleComponent for UpdatePageModel { self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateUserPkgsRemove(pkgs)); } UpdatePageMsg::UpdateAll => { + let online = util::checkonline(); + if !online { + sender.output(AppMsg::CheckNetwork); + self.online = false; + return; + } info!("UpdatePageMsg::UpdateAll"); let systype = self.systype.clone(); let usertype = self.usertype.clone(); @@ -373,6 +415,9 @@ impl SimpleComponent for UpdatePageModel { UpdatePageMsg::FailedWorking => { REBUILD_BROKER.send(RebuildMsg::FinishError(None)); } + UpdatePageMsg::UpdateOnline(online) => { + self.set_online(online); + } } } } diff --git a/src/ui/window.rs b/src/ui/window.rs index 201cd21..be26ba6 100644 --- a/src/ui/window.rs +++ b/src/ui/window.rs @@ -2,9 +2,13 @@ use crate::{ config, parse::{ config::{editconfig, getconfig}, - packages::{AppData, LicenseEnum, PkgMaintainer, Platform}, + packages::{AppData, LicenseEnum, PkgMaintainer, Platform}, util, + }, + ui::{ + installedpage::InstalledItem, pkgpage::PkgPageInit, rebuild::RebuildMsg, + unavailabledialog::UnavailableDialogMsg, updatepage::UNAVAILABLE_BROKER, + welcome::WelcomeMsg, }, - ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg, rebuild::RebuildMsg, updatepage::UNAVAILABLE_BROKER, unavailabledialog::UnavailableDialogMsg}, APPINFO, }; use adw::prelude::*; @@ -29,10 +33,12 @@ use super::{ pkgpage::{self, InstallType, PkgInitModel, PkgModel, PkgMsg, WorkPkg}, pkgtile::PkgTile, preferencespage::{PreferencesPageModel, PreferencesPageMsg}, + rebuild::RebuildModel, searchpage::{SearchItem, SearchPageModel, SearchPageMsg}, + unavailabledialog::UnavailableItemModel, updatepage::{UpdateItem, UpdatePageInit, UpdatePageModel, UpdatePageMsg, UpdateType}, welcome::WelcomeModel, - windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg}, rebuild::RebuildModel, unavailabledialog::UnavailableItemModel, + windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg}, }; pub static REBUILD_BROKER: MessageBroker = MessageBroker::new(); @@ -113,6 +119,7 @@ pub struct AppModel { installedpagebusy: Vec<(String, InstallType)>, #[tracker::no_eq] rebuild: Controller, + online: bool, } #[derive(Debug)] @@ -120,6 +127,7 @@ pub enum AppMsg { UpdateSysconfig(Option), UpdateFlake(Option, Option), TryLoad, + UpdateDB, LoadConfig(NixDataConfig), Close, LoadError(String, String), @@ -153,6 +161,7 @@ pub enum AppMsg { UpdateRecPkgs(Vec), SetDarkMode(bool), GetUnavailableItems(HashMap, HashMap, UpdateType), + CheckNetwork, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -171,6 +180,7 @@ pub enum AppAsyncMsg { UpdateRecPkgs(Vec), UpdateInstalledPkgs(HashSet, HashMap), LoadCategory(PkgCategory, Vec, Vec), + SetNetwork(bool) } #[relm4::component(pub)] @@ -465,6 +475,8 @@ impl Component for AppModel { debug!("userpkgtype: {:?}", userpkgtype); debug!("syspkgtype: {:?}", syspkgtype); + let online = util::checkonline(); + let windowloading = WindowAsyncHandler::builder() .detach_worker(()) .forward(sender.input_sender(), identity); @@ -476,6 +488,7 @@ impl Component for AppModel { userpkgs: userpkgtype.clone(), syspkgs: syspkgtype.clone(), config: config.clone(), + online, }) .forward(sender.input_sender(), identity); let searchpage = SearchPageModel::builder() @@ -493,6 +506,7 @@ impl Component for AppModel { systype: syspkgtype.clone(), usertype: userpkgtype.clone(), config: config.clone(), + online, }) .forward(sender.input_sender(), identity); let rebuild = RebuildModel::builder() @@ -532,6 +546,7 @@ impl Component for AppModel { viewstack, installedpagebusy: vec![], rebuild, + online, tracker: 0, }; @@ -604,7 +619,12 @@ impl Component for AppModel { } #[tokio::main] - async fn update(&mut self, msg: Self::Input, sender: ComponentSender, _root: &Self::Root) { + async fn update( + &mut self, + msg: Self::Input, + sender: ComponentSender, + _root: &Self::Root, + ) { self.reset(); match msg { AppMsg::TryLoad => { @@ -615,6 +635,12 @@ impl Component for AppModel { self.config.clone(), )); } + AppMsg::UpdateDB => { + self.windowloading.emit(WindowAsyncHandlerMsg::UpdateDB( + self.syspkgtype.clone(), + self.userpkgtype.clone(), + )); + } AppMsg::LoadConfig(config) => { info!("AppMsg::LoadConfig"); self.config = config; @@ -758,12 +784,12 @@ impl Component for AppModel { self.categoryrec = categoryrec; self.categoryall = categoryall; - self.page = Page::FrontPage; self.pkgpage.emit(PkgMsg::UpdateConfig(self.config.clone())); self.updatepage .emit(UpdatePageMsg::UpdateConfig(self.config.clone())); sender.input(AppMsg::UpdateRecPkgs(recommendedapps)); let mut cat_guard = self.categories.guard(); + cat_guard.clear(); for c in vec![ PkgCategory::Audio, PkgCategory::Development, @@ -824,7 +850,10 @@ impl Component for AppModel { .and_then(|x| x.get("C")) .map(|x| x.to_string()) .unwrap_or_default(), - installeduser: installeduser.contains_key(&match userpkgtype { UserPkgs::Env => pname.0, UserPkgs::Profile => pkg.to_string() }), + installeduser: installeduser.contains_key(&match userpkgtype { + UserPkgs::Env => pname.0, + UserPkgs::Profile => pkg.to_string(), + }), installedsystem: installedsystem.contains(&pkg), }) } @@ -835,6 +864,7 @@ impl Component for AppModel { } AppMsg::OpenPkg(pkg) => { info!("AppMsg::OpenPkg {}", pkg); + sender.input(AppMsg::CheckNetwork); if let Ok(pool) = &SqlitePool::connect(&format!("sqlite://{}", self.pkgdb)).await { let pkgdata: Result< ( @@ -1371,10 +1401,7 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = .fetch_one(latestpool) .await .unwrap(); - debug!( - "PROFILE: {} {} {}", - installedpkg, version, newver - ); + debug!("PROFILE: {} {} {}", installedpkg, version, newver); if version != newver { updateuseritems.push(UpdateItem { name, @@ -1551,6 +1578,9 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = sender.input(AppMsg::SetSearch(false)) } } + if name == "updates" && self.online { + sender.input(AppMsg::CheckNetwork); + } } AppMsg::SetVsBar(vsbar) => { self.set_showvsbar(vsbar); @@ -1869,7 +1899,7 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = .as_ref() .and_then(|x| x.cached.as_ref()) .map(|x| x[0].name.clone()), - message: msg + message: msg, }) } else { unavailableuser.push(UnavailableItemModel { @@ -1885,7 +1915,7 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = .as_ref() .and_then(|x| x.cached.as_ref()) .map(|x| x[0].name.clone()), - message: msg + message: msg, }) } } else { @@ -1894,7 +1924,7 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = name: pkg.to_string(), pname: String::new(), icon: None, - message: msg + message: msg, }) } } @@ -1921,7 +1951,7 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = .as_ref() .and_then(|x| x.cached.as_ref()) .map(|x| x[0].name.clone()), - message: msg + message: msg, }) } else { unavailablesys.push(UnavailableItemModel { @@ -1937,7 +1967,7 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = .as_ref() .and_then(|x| x.cached.as_ref()) .map(|x| x[0].name.clone()), - message: msg + message: msg, }) } } else { @@ -1946,19 +1976,39 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = name: pkg.to_string(), pname: String::new(), icon: None, - message: msg + message: msg, }) } } - } - UNAVAILABLE_BROKER.send(UnavailableDialogMsg::Show(unavailableuser, unavailablesys, updatetype)); + UNAVAILABLE_BROKER.send(UnavailableDialogMsg::Show( + unavailableuser, + unavailablesys, + updatetype, + )); + }); + } + AppMsg::CheckNetwork => { + let selfonline = self.online; + let senderclone = sender.clone(); + sender.oneshot_command(async move { + info!("AppMsg::CheckNetwork"); + let online = util::checkonline(); + if online && !selfonline { + senderclone.input(AppMsg::UpdateDB); + } + AppAsyncMsg::SetNetwork(online) }); } } } - fn update_cmd(&mut self, msg: Self::CommandOutput, sender: ComponentSender, _root: &Self::Root) { + fn update_cmd( + &mut self, + msg: Self::CommandOutput, + sender: ComponentSender, + _root: &Self::Root, + ) { match msg { AppAsyncMsg::Search(search, pkgitems) => { if search == self.searchquery { @@ -1990,7 +2040,11 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = debug!("Got recommended apps guard"); for item in recommendedapps_guard.iter_mut() { debug!("Got item {}", item.pkg); - item.installeduser = self.installeduserpkgs.contains_key(match self.userpkgtype { UserPkgs::Env => &item.pname, UserPkgs::Profile => &item.pkg }); + item.installeduser = + self.installeduserpkgs.contains_key(match self.userpkgtype { + UserPkgs::Env => &item.pname, + UserPkgs::Profile => &item.pkg, + }); item.installedsystem = self.installedsystempkgs.contains(&item.pkg); } if self.searching { @@ -2006,6 +2060,11 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute = self.categorypage .emit(CategoryPageMsg::Open(category, catrec, catall)); } + AppAsyncMsg::SetNetwork(online) => { + self.online = online; + self.updatepage.emit(UpdatePageMsg::UpdateOnline(online)); + self.pkgpage.emit(PkgMsg::UpdateOnline(online)); + } } } } diff --git a/src/ui/windowloading.rs b/src/ui/windowloading.rs index d8de8be..fbfed9a 100644 --- a/src/ui/windowloading.rs +++ b/src/ui/windowloading.rs @@ -18,6 +18,7 @@ pub struct WindowAsyncHandler; #[derive(Debug)] pub enum WindowAsyncHandlerMsg { CheckCache(SystemPkgs, UserPkgs, NixDataConfig), + UpdateDB(SystemPkgs, UserPkgs), } impl Worker for WindowAsyncHandler { @@ -42,9 +43,14 @@ impl Worker for WindowAsyncHandler { Ok(p) => p, Err(e) => { error!("Error getting NixOS pkgs: {}", e); + sender.output(AppMsg::LoadError( + String::from("Error retrieving NixOS package database"), + e.to_string(), + )); return; } }; + let pool = SqlitePool::connect(&format!("sqlite://{}", pkgdb)) .await .unwrap(); @@ -381,6 +387,50 @@ impl Worker for WindowAsyncHandler { )); }); } + WindowAsyncHandlerMsg::UpdateDB(syspkgs, userpkgs) => { + relm4::spawn(async move { + let _pkgdb = match nix_data::cache::nixos::nixospkgs().await { + Ok(p) => p, + Err(e) => { + error!("Error getting NixOS pkgs: {}", e); + sender.output(AppMsg::LoadError( + String::from("Error retrieving NixOS package database"), + e.to_string(), + )); + return; + } + }; + + let _nixpkgsdb = match userpkgs { + UserPkgs::Profile => { + if let Ok(x) = nix_data::cache::profile::nixpkgslatest().await { + Some(x) + } else { + None + } + } + UserPkgs::Env => None, + }; + + let _systemdb = match syspkgs { + SystemPkgs::None => None, + SystemPkgs::Legacy => { + if let Ok(x) = nix_data::cache::channel::legacypkgs().await { + Some(x) + } else { + None + } + } + SystemPkgs::Flake => { + if let Ok(x) = nix_data::cache::flakes::flakespkgs().await { + Some(x) + } else { + None + } + } + }; + }); + } } } } @@ -467,8 +517,7 @@ impl SimpleComponent for LoadErrorModel { } LoadErrorMsg::Close => { sender.output(AppMsg::Close); - } - // LoadErrorMsg::Preferences => sender.output(AppMsg::ShowPrefMenu), + } // LoadErrorMsg::Preferences => sender.output(AppMsg::ShowPrefMenu), } } }