mirror of
https://github.com/snowfallorg/nix-software-center.git
synced 2024-08-17 09:00:35 +03:00
Add rebuild output window
This commit is contained in:
parent
f355d40336
commit
0e9d1105f7
65
Cargo.lock
generated
65
Cargo.lock
generated
@ -198,9 +198,9 @@ checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.12.1"
|
||||
version = "1.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da"
|
||||
checksum = "5aec14f5d4e6e3f927cd0c81f72e5710d95ee9019fbeb4b3021193867491bfd8"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@ -250,9 +250,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
version = "1.0.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
@ -1230,9 +1230,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.20"
|
||||
version = "0.14.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
|
||||
checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@ -1617,7 +1617,7 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
[[package]]
|
||||
name = "nix-data"
|
||||
version = "0.0.2"
|
||||
source = "git+https://github.com/snowflakelinux/nix-data?rev=a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95#a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95"
|
||||
source = "git+https://github.com/snowflakelinux/nix-data#33479e595f14142f15fb6ec29cc585352c2c7703"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"csv",
|
||||
@ -1669,6 +1669,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"sha256",
|
||||
"sourceview5",
|
||||
"spdx",
|
||||
"sqlx",
|
||||
"tokio",
|
||||
@ -1751,9 +1752,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.15.0"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
@ -1967,14 +1968,14 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.6"
|
||||
version = "0.17.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c"
|
||||
checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"miniz_oxide 0.5.4",
|
||||
"miniz_oxide 0.6.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2500,6 +2501,42 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sourceview5"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "922cc28db6bec169868319262dd932f6403e5ce95dad0d2bb6fcc9ac03be7f10"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"gdk-pixbuf",
|
||||
"gdk4",
|
||||
"gio",
|
||||
"glib",
|
||||
"gtk4",
|
||||
"libc",
|
||||
"pango",
|
||||
"sourceview5-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sourceview5-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73277b2a53923aeecd212a89379dce7e6c687fe35fe6dd41d9b0d7b3d4c2eb0b"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gdk4-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk4-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spdx"
|
||||
version = "0.9.0"
|
||||
@ -2777,9 +2814,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65"
|
||||
checksum = "9f71e422515e83e3ab8a03d4781d05ebf864fc61f4546e6ecffa58cbd34181a0"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"jpeg-decoder",
|
||||
|
@ -9,6 +9,7 @@ relm4 = { version = "0.5.0-beta.4", features = ["all"] }
|
||||
relm4-components = { package = "relm4-components", version = "0.5.0-beta.4"}
|
||||
adw = { package = "libadwaita", version = "0.2", features = ["v1_2", "gtk_v4_6"] }
|
||||
gtk = { package = "gtk4", version = "0.5", features = ["v4_6"] }
|
||||
sourceview5 = { version = "0.5", features = ["v5_4"] }
|
||||
tokio = { version = "1.21", features = ["rt", "macros", "time", "rt-multi-thread", "sync", "process"] }
|
||||
tracker = "0.1"
|
||||
|
||||
@ -17,7 +18,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_yaml = "0.9"
|
||||
|
||||
nix-editor = "0.3.0-beta.1"
|
||||
nix-data = { git = "https://github.com/snowflakelinux/nix-data", rev = "a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95" }
|
||||
nix-data = { git = "https://github.com/snowflakelinux/nix-data" }
|
||||
|
||||
sqlx = { version = "0.6", features = [ "runtime-tokio-native-tls" , "sqlite" ] }
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
pango
|
||||
pkg-config
|
||||
polkit
|
||||
sqlite
|
||||
wrapGAppsHook4
|
||||
nixos-appstream-data
|
||||
];
|
||||
|
@ -1,12 +1,13 @@
|
||||
use super::pkgpage::{InstallType, PkgAction, PkgMsg, WorkPkg};
|
||||
use super::window::{SystemPkgs, UserPkgs};
|
||||
use super::rebuild::RebuildMsg;
|
||||
use super::window::{SystemPkgs, UserPkgs, REBUILD_BROKER};
|
||||
use log::*;
|
||||
use nix_data::config::configfile::NixDataConfig;
|
||||
use relm4::*;
|
||||
use std::error::Error;
|
||||
use anyhow::{Result, anyhow};
|
||||
use std::path::Path;
|
||||
use std::process::Stdio;
|
||||
use std::{fs, io};
|
||||
use std::fs;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
|
||||
|
||||
#[tracker::track]
|
||||
@ -265,6 +266,7 @@ impl Worker for InstallAsyncHandler {
|
||||
}
|
||||
},
|
||||
InstallType::System => {
|
||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||
if let Some(systemconfig) = systemconfig {
|
||||
match work.action {
|
||||
PkgAction::Install => {
|
||||
@ -281,12 +283,15 @@ impl Worker for InstallAsyncHandler {
|
||||
{
|
||||
Ok(b) => {
|
||||
if b {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishSuccess);
|
||||
sender.output(PkgMsg::FinishedProcess(work))
|
||||
} else {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishError(None));
|
||||
sender.output(PkgMsg::FailedProcess(work))
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishError(None));
|
||||
sender.output(PkgMsg::FailedProcess(work));
|
||||
warn!("Error installing system package: {}", e);
|
||||
}
|
||||
@ -307,12 +312,15 @@ impl Worker for InstallAsyncHandler {
|
||||
{
|
||||
Ok(b) => {
|
||||
if b {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishSuccess);
|
||||
sender.output(PkgMsg::FinishedProcess(work))
|
||||
} else {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishError(None));
|
||||
sender.output(PkgMsg::FailedProcess(work))
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishError(None));
|
||||
sender.output(PkgMsg::FailedProcess(work));
|
||||
warn!("Error removing system package: {}", e);
|
||||
}
|
||||
@ -344,7 +352,7 @@ async fn installsys(
|
||||
systemconfig: String,
|
||||
flakeargs: Option<String>,
|
||||
_sender: ComponentSender<InstallAsyncHandler>,
|
||||
) -> Result<bool, Box<dyn Error>> {
|
||||
) -> Result<bool> {
|
||||
let mut p = pkg;
|
||||
let f = fs::read_to_string(&systemconfig)?;
|
||||
if let Ok(s) = nix_editor::read::getwithvalue(&f, "environment.systemPackages") {
|
||||
@ -352,10 +360,7 @@ async fn installsys(
|
||||
p = format!("pkgs.{}", p);
|
||||
}
|
||||
} else {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Failed to write configuration.nix",
|
||||
)));
|
||||
return Err(anyhow!("Failed to write configuration.nix"));
|
||||
}
|
||||
|
||||
let out = match action {
|
||||
@ -363,10 +368,7 @@ async fn installsys(
|
||||
match nix_editor::write::addtoarr(&f, "environment.systemPackages", vec![p]) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Failed to write configuration.nix",
|
||||
)))
|
||||
return Err(anyhow!("Failed to write configuration.nix"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -374,10 +376,7 @@ async fn installsys(
|
||||
match nix_editor::write::rmarr(&f, "environment.systemPackages", vec![p]) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return Err(Box::new(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"Failed to write configuration.nix",
|
||||
)))
|
||||
return Err(anyhow!("Failed to write configuration.nix"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -419,13 +418,12 @@ async fn installsys(
|
||||
.arg(&systemconfig)
|
||||
.arg("--")
|
||||
.arg("switch")
|
||||
.arg("--impure")
|
||||
.args(&rebuildargs)
|
||||
.stderr(Stdio::piped())
|
||||
.stdin(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
// sender.input(InstallAsyncHandlerMsg::SetPid(cmd.id()));
|
||||
|
||||
cmd.stdin.take().unwrap().write_all(out.as_bytes()).await?;
|
||||
let stderr = cmd.stderr.take().unwrap();
|
||||
let reader = tokio::io::BufReader::new(stderr);
|
||||
@ -433,6 +431,7 @@ async fn installsys(
|
||||
let mut lines = reader.lines();
|
||||
while let Ok(Some(line)) = lines.next_line().await {
|
||||
trace!("CAUGHT LINE: {}", line);
|
||||
REBUILD_BROKER.send(RebuildMsg::UpdateText(line));
|
||||
}
|
||||
if cmd.wait().await?.success() {
|
||||
Ok(true)
|
||||
|
@ -1,17 +1,17 @@
|
||||
pub mod window;
|
||||
pub mod windowloading;
|
||||
pub mod pkgtile;
|
||||
pub mod categories;
|
||||
pub mod pkgpage;
|
||||
pub mod screenshotfactory;
|
||||
pub mod installworker;
|
||||
pub mod searchpage;
|
||||
pub mod installedpage;
|
||||
pub mod updatepage;
|
||||
pub mod updatedialog;
|
||||
pub mod updateworker;
|
||||
pub mod about;
|
||||
pub mod preferencespage;
|
||||
pub mod categories;
|
||||
pub mod categorypage;
|
||||
pub mod categorytile;
|
||||
pub mod installedpage;
|
||||
pub mod installworker;
|
||||
pub mod pkgpage;
|
||||
pub mod pkgtile;
|
||||
pub mod preferencespage;
|
||||
pub mod rebuild;
|
||||
pub mod screenshotfactory;
|
||||
pub mod searchpage;
|
||||
pub mod updatepage;
|
||||
pub mod updateworker;
|
||||
pub mod welcome;
|
||||
pub mod window;
|
||||
pub mod windowloading;
|
||||
|
244
src/ui/rebuild.rs
Normal file
244
src/ui/rebuild.rs
Normal file
@ -0,0 +1,244 @@
|
||||
use super::window::AppMsg;
|
||||
use adw::prelude::*;
|
||||
use log::{info, trace};
|
||||
use relm4::*;
|
||||
use sourceview5::prelude::*;
|
||||
|
||||
#[tracker::track]
|
||||
pub struct RebuildModel {
|
||||
hidden: bool,
|
||||
text: String,
|
||||
status: RebuildStatus,
|
||||
config: String,
|
||||
path: String,
|
||||
flake: Option<String>,
|
||||
scheme: Option<sourceview5::StyleScheme>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RebuildMsg {
|
||||
Show,
|
||||
FinishSuccess,
|
||||
FinishError(Option<String>),
|
||||
UpdateText(String),
|
||||
Close,
|
||||
SetScheme(String),
|
||||
Quit,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum RebuildStatus {
|
||||
Building,
|
||||
Success,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for RebuildModel {
|
||||
type Init = gtk::Window;
|
||||
type Input = RebuildMsg;
|
||||
type Output = AppMsg;
|
||||
type Widgets = RebuildWidgets;
|
||||
|
||||
view! {
|
||||
dialog = adw::Window {
|
||||
set_transient_for: Some(&parent_window),
|
||||
set_modal: true,
|
||||
#[track(model.changed(RebuildModel::hidden()))]
|
||||
set_default_width: 500,
|
||||
#[track(model.changed(RebuildModel::hidden()))]
|
||||
set_default_height: 200,//295),
|
||||
set_resizable: true,
|
||||
#[watch]
|
||||
set_visible: !model.hidden,
|
||||
add_css_class: "dialog",
|
||||
add_css_class: "message",
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
#[name(statusstack)]
|
||||
gtk::Stack {
|
||||
set_margin_top: 20,
|
||||
set_transition_type: gtk::StackTransitionType::Crossfade,
|
||||
set_vhomogeneous: false,
|
||||
#[name(building)]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
gtk::Spinner {
|
||||
#[watch]
|
||||
set_spinning: true,
|
||||
set_height_request: 60,
|
||||
},
|
||||
gtk::Label {
|
||||
set_label: "Building...",
|
||||
add_css_class: "title-1",
|
||||
},
|
||||
},
|
||||
#[name(success)]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
gtk::Image {
|
||||
add_css_class: "success",
|
||||
set_icon_name: Some("object-select-symbolic"),
|
||||
set_pixel_size: 128,
|
||||
},
|
||||
gtk::Label {
|
||||
set_label: "Done!",
|
||||
add_css_class: "title-1",
|
||||
},
|
||||
gtk::Label {
|
||||
set_label: "Rebuild successful!",
|
||||
add_css_class: "dim-label",
|
||||
}
|
||||
},
|
||||
#[name(error)]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 10,
|
||||
gtk::Image {
|
||||
add_css_class: "error",
|
||||
set_icon_name: Some("dialog-error-symbolic"),
|
||||
set_pixel_size: 128,
|
||||
},
|
||||
gtk::Label {
|
||||
set_label: "Error!",
|
||||
add_css_class: "title-1",
|
||||
},
|
||||
gtk::Label {
|
||||
set_label: "Rebuild failed! See below for error message.",
|
||||
add_css_class: "dim-label",
|
||||
}
|
||||
}
|
||||
},
|
||||
gtk::Frame {
|
||||
set_margin_all: 20,
|
||||
#[name(scrollwindow)]
|
||||
gtk::ScrolledWindow {
|
||||
set_max_content_height: 500,
|
||||
set_min_content_height: 100,
|
||||
#[name(outview)]
|
||||
sourceview5::View {
|
||||
set_editable: false,
|
||||
set_cursor_visible: false,
|
||||
set_monospace: true,
|
||||
set_top_margin: 5,
|
||||
set_bottom_margin: 5,
|
||||
set_left_margin: 5,
|
||||
set_vexpand: true,
|
||||
set_hexpand: true,
|
||||
set_vscroll_policy: gtk::ScrollablePolicy::Minimum,
|
||||
#[wrap(Some)]
|
||||
set_buffer: outbuf = &sourceview5::Buffer {
|
||||
#[track(model.changed(RebuildModel::scheme()))]
|
||||
set_style_scheme: model.scheme.as_ref(),
|
||||
#[track(model.changed(RebuildModel::text()))]
|
||||
set_text: &model.text,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
add_css_class: "dialog-action-area",
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_homogeneous: true,
|
||||
#[track(model.changed(RebuildModel::status()))]
|
||||
set_visible: model.status != RebuildStatus::Building,
|
||||
gtk::Button {
|
||||
set_label: "Close",
|
||||
#[track(model.changed(RebuildModel::status()))]
|
||||
set_visible: model.status != RebuildStatus::Building,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(RebuildMsg::Close)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pre_view() {
|
||||
match model.status {
|
||||
RebuildStatus::Building => {
|
||||
statusstack.set_visible_child(building);
|
||||
}
|
||||
RebuildStatus::Success => statusstack.set_visible_child(success),
|
||||
RebuildStatus::Error => statusstack.set_visible_child(error),
|
||||
}
|
||||
}
|
||||
|
||||
fn post_view() {
|
||||
let adj = scrollwindow.vadjustment();
|
||||
if model.status == RebuildStatus::Building {
|
||||
adj.set_upper(adj.upper() + 20.0);
|
||||
}
|
||||
adj.set_value(adj.upper());
|
||||
if model.status != RebuildStatus::Building {
|
||||
outview.scroll_to_mark(&outview.buffer().get_insert(), 0.0, true, 0.0, 0.0);
|
||||
scrollwindow.hadjustment().set_value(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
parent_window: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
|
||||
let model = RebuildModel {
|
||||
hidden: true,
|
||||
text: String::new(),
|
||||
status: RebuildStatus::Building,
|
||||
config: String::new(),
|
||||
path: String::new(),
|
||||
flake: None,
|
||||
scheme: None,
|
||||
tracker: 0,
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||
self.reset();
|
||||
match msg {
|
||||
RebuildMsg::Show => {
|
||||
self.update_hidden(|x| *x = false);
|
||||
self.update_text(|x| x.clear());
|
||||
self.set_status(RebuildStatus::Building);
|
||||
}
|
||||
RebuildMsg::UpdateText(s) => {
|
||||
info!("RebuildMsg::UpdateText({})", s);
|
||||
let newtext = if self.text.is_empty() {
|
||||
s
|
||||
} else {
|
||||
format!("{}\n{}", self.text, s)
|
||||
};
|
||||
self.set_text(newtext);
|
||||
trace!("NEWTEXT: {}", self.text);
|
||||
}
|
||||
RebuildMsg::FinishSuccess => {
|
||||
self.set_status(RebuildStatus::Success);
|
||||
}
|
||||
RebuildMsg::FinishError(msg) => {
|
||||
if let Some(s) = msg {
|
||||
self.set_text(s)
|
||||
}
|
||||
self.update_hidden(|x| *x = false);
|
||||
self.set_status(RebuildStatus::Error);
|
||||
}
|
||||
RebuildMsg::Close => {
|
||||
self.update_hidden(|x| *x = true);
|
||||
self.update_text(|x| x.clear());
|
||||
}
|
||||
RebuildMsg::SetScheme(scheme) => {
|
||||
self.set_scheme(sourceview5::StyleSchemeManager::default().scheme(&scheme));
|
||||
}
|
||||
RebuildMsg::Quit => {
|
||||
sender.output(AppMsg::Close);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
use adw::prelude::*;
|
||||
use relm4::*;
|
||||
|
||||
use super::updatepage::UpdatePageMsg;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UpdateDialogModel {
|
||||
hidden: bool,
|
||||
message: String,
|
||||
done: bool,
|
||||
failed: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UpdateDialogMsg {
|
||||
Show(String),
|
||||
Close,
|
||||
Done,
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for UpdateDialogModel {
|
||||
type Init = gtk::Window;
|
||||
type Input = UpdateDialogMsg;
|
||||
type Output = UpdatePageMsg;
|
||||
type Widgets = UpdateDialogWidgets;
|
||||
|
||||
view! {
|
||||
dialog = adw::Window {
|
||||
#[watch]
|
||||
set_visible: !model.hidden,
|
||||
set_transient_for: Some(&parent_window),
|
||||
set_modal: true,
|
||||
set_resizable: false,
|
||||
set_default_width: 500,
|
||||
set_default_height: 200,
|
||||
add_css_class: "dialog",
|
||||
add_css_class: "message",
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_halign: gtk::Align::Fill,
|
||||
set_valign: gtk::Align::Fill,
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_halign: gtk::Align::Center,
|
||||
set_valign: gtk::Align::Center,
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
set_margin_all: 15,
|
||||
set_spacing: 10,
|
||||
gtk::Label {
|
||||
#[watch]
|
||||
set_visible: !model.message.is_empty(),
|
||||
add_css_class: "title-1",
|
||||
#[watch]
|
||||
set_label: &model.message,
|
||||
},
|
||||
if model.done {
|
||||
gtk::Image {
|
||||
add_css_class: "success",
|
||||
set_icon_name: Some("emblem-ok-symbolic"),
|
||||
set_pixel_size: 128,
|
||||
}
|
||||
} else if model.failed {
|
||||
gtk::Image {
|
||||
add_css_class: "error",
|
||||
set_icon_name: Some("dialog-error-symbolic"),
|
||||
set_pixel_size: 128,
|
||||
}
|
||||
} else {
|
||||
gtk::Spinner {
|
||||
#[watch]
|
||||
set_visible: !model.done,
|
||||
#[watch]
|
||||
set_spinning: !model.done,
|
||||
}
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
#[watch]
|
||||
set_visible: model.done || model.failed,
|
||||
add_css_class: "dialog-action-area",
|
||||
set_valign: gtk::Align::End,
|
||||
set_vexpand: true,
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_homogeneous: true,
|
||||
gtk::Button {
|
||||
set_label: "Close",
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(UpdateDialogMsg::Close);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
parent_window: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let model = UpdateDialogModel {
|
||||
hidden: true,
|
||||
done: false,
|
||||
failed: false,
|
||||
message: String::default(),
|
||||
};
|
||||
|
||||
let widgets = view_output!();
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
|
||||
match msg {
|
||||
UpdateDialogMsg::Show(desc) => {
|
||||
self.message = desc;
|
||||
self.hidden = false;
|
||||
self.done = false;
|
||||
self.failed = false;
|
||||
}
|
||||
UpdateDialogMsg::Close => {
|
||||
self.hidden = true;
|
||||
}
|
||||
UpdateDialogMsg::Done => {
|
||||
self.done = true;
|
||||
}
|
||||
UpdateDialogMsg::Failed => {
|
||||
self.failed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use crate::APPINFO;
|
||||
|
||||
use super::{pkgpage::InstallType, window::*, updatedialog::{UpdateDialogModel, UpdateDialogMsg}, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}};
|
||||
use super::{pkgpage::InstallType, window::*, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}, rebuild::RebuildMsg};
|
||||
use adw::prelude::*;
|
||||
use nix_data::config::configfile::NixDataConfig;
|
||||
use relm4::{factory::*, gtk::pango, *};
|
||||
@ -16,8 +16,6 @@ pub struct UpdatePageModel {
|
||||
updatesystemlist: FactoryVecDeque<UpdateItemModel>,
|
||||
channelupdate: Option<(String, String)>,
|
||||
#[tracker::no_eq]
|
||||
updatedialog: Controller<UpdateDialogModel>,
|
||||
#[tracker::no_eq]
|
||||
updateworker: WorkerController<UpdateAsyncHandler>,
|
||||
config: NixDataConfig,
|
||||
systype: SystemPkgs,
|
||||
@ -34,11 +32,10 @@ pub enum UpdatePageMsg {
|
||||
UpdateSystem,
|
||||
UpdateAllUser,
|
||||
UpdateUser(String),
|
||||
UpdateChannels,
|
||||
UpdateSystemAndChannels,
|
||||
// UpdateChannels,
|
||||
// UpdateSystemAndChannels,
|
||||
UpdateAll,
|
||||
DoneWorking,
|
||||
DoneLoading,
|
||||
FailedWorking,
|
||||
}
|
||||
|
||||
@ -87,101 +84,101 @@ impl SimpleComponent for UpdatePageModel {
|
||||
}
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_hexpand: true,
|
||||
#[watch]
|
||||
set_visible: model.channelupdate.is_some(),
|
||||
gtk::Label {
|
||||
set_halign: gtk::Align::Start,
|
||||
add_css_class: "title-4",
|
||||
set_label: "Channels",
|
||||
},
|
||||
},
|
||||
gtk::ListBox {
|
||||
set_valign: gtk::Align::Start,
|
||||
add_css_class: "boxed-list",
|
||||
set_selection_mode: gtk::SelectionMode::None,
|
||||
#[watch]
|
||||
set_visible: model.channelupdate.is_some(),
|
||||
adw::PreferencesRow {
|
||||
set_activatable: false,
|
||||
set_can_focus: false,
|
||||
#[wrap(Some)]
|
||||
set_child = >k::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_hexpand: true,
|
||||
set_spacing: 10,
|
||||
set_margin_all: 10,
|
||||
adw::Bin {
|
||||
set_valign: gtk::Align::Center,
|
||||
gtk::Image {
|
||||
add_css_class: "icon-dropshadow",
|
||||
set_halign: gtk::Align::Start,
|
||||
set_icon_name: Some("application-x-addon"),
|
||||
set_pixel_size: 64,
|
||||
}
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_halign: gtk::Align::Fill,
|
||||
set_valign: gtk::Align::Center,
|
||||
set_hexpand: true,
|
||||
set_spacing: 2,
|
||||
gtk::Label {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_label: "nixos",
|
||||
set_ellipsize: pango::EllipsizeMode::End,
|
||||
set_lines: 1,
|
||||
set_wrap: true,
|
||||
set_max_width_chars: 0,
|
||||
},
|
||||
gtk::Label {
|
||||
set_halign: gtk::Align::Start,
|
||||
add_css_class: "dim-label",
|
||||
add_css_class: "caption",
|
||||
set_label: {
|
||||
&(if let Some((old, new)) = &model.channelupdate {
|
||||
format!("{} → {}", old, new)
|
||||
} else {
|
||||
String::default()
|
||||
})
|
||||
},
|
||||
set_visible: model.channelupdate.is_some(),
|
||||
set_ellipsize: pango::EllipsizeMode::End,
|
||||
set_lines: 1,
|
||||
set_wrap: true,
|
||||
set_max_width_chars: 0,
|
||||
},
|
||||
},
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
set_halign: gtk::Align::End,
|
||||
set_valign: gtk::Align::Center,
|
||||
gtk::Button {
|
||||
add_css_class: "suggested-action",
|
||||
set_valign: gtk::Align::Center,
|
||||
set_halign: gtk::Align::End,
|
||||
set_label: "Update channel and system",
|
||||
set_can_focus: false,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(UpdatePageMsg::UpdateSystemAndChannels);
|
||||
}
|
||||
},
|
||||
gtk::Button {
|
||||
set_valign: gtk::Align::Center,
|
||||
set_halign: gtk::Align::End,
|
||||
set_label: "Update channel only",
|
||||
set_can_focus: false,
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(UpdatePageMsg::UpdateChannels);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// gtk::Box {
|
||||
// set_orientation: gtk::Orientation::Horizontal,
|
||||
// set_hexpand: true,
|
||||
// #[watch]
|
||||
// set_visible: model.channelupdate.is_some(),
|
||||
// gtk::Label {
|
||||
// set_halign: gtk::Align::Start,
|
||||
// add_css_class: "title-4",
|
||||
// set_label: "Channels",
|
||||
// },
|
||||
// },
|
||||
// gtk::ListBox {
|
||||
// set_valign: gtk::Align::Start,
|
||||
// add_css_class: "boxed-list",
|
||||
// set_selection_mode: gtk::SelectionMode::None,
|
||||
// #[watch]
|
||||
// set_visible: model.channelupdate.is_some(),
|
||||
// adw::PreferencesRow {
|
||||
// set_activatable: false,
|
||||
// set_can_focus: false,
|
||||
// #[wrap(Some)]
|
||||
// set_child = >k::Box {
|
||||
// set_orientation: gtk::Orientation::Horizontal,
|
||||
// set_hexpand: true,
|
||||
// set_spacing: 10,
|
||||
// set_margin_all: 10,
|
||||
// adw::Bin {
|
||||
// set_valign: gtk::Align::Center,
|
||||
// gtk::Image {
|
||||
// add_css_class: "icon-dropshadow",
|
||||
// set_halign: gtk::Align::Start,
|
||||
// set_icon_name: Some("application-x-addon"),
|
||||
// set_pixel_size: 64,
|
||||
// }
|
||||
// },
|
||||
// gtk::Box {
|
||||
// set_orientation: gtk::Orientation::Vertical,
|
||||
// set_halign: gtk::Align::Fill,
|
||||
// set_valign: gtk::Align::Center,
|
||||
// set_hexpand: true,
|
||||
// set_spacing: 2,
|
||||
// gtk::Label {
|
||||
// set_halign: gtk::Align::Start,
|
||||
// set_label: "nixos",
|
||||
// set_ellipsize: pango::EllipsizeMode::End,
|
||||
// set_lines: 1,
|
||||
// set_wrap: true,
|
||||
// set_max_width_chars: 0,
|
||||
// },
|
||||
// gtk::Label {
|
||||
// set_halign: gtk::Align::Start,
|
||||
// add_css_class: "dim-label",
|
||||
// add_css_class: "caption",
|
||||
// set_label: {
|
||||
// &(if let Some((old, new)) = &model.channelupdate {
|
||||
// format!("{} → {}", old, new)
|
||||
// } else {
|
||||
// String::default()
|
||||
// })
|
||||
// },
|
||||
// set_visible: model.channelupdate.is_some(),
|
||||
// set_ellipsize: pango::EllipsizeMode::End,
|
||||
// set_lines: 1,
|
||||
// set_wrap: true,
|
||||
// set_max_width_chars: 0,
|
||||
// },
|
||||
// },
|
||||
// gtk::Box {
|
||||
// set_orientation: gtk::Orientation::Vertical,
|
||||
// set_spacing: 5,
|
||||
// set_halign: gtk::Align::End,
|
||||
// set_valign: gtk::Align::Center,
|
||||
// gtk::Button {
|
||||
// add_css_class: "suggested-action",
|
||||
// set_valign: gtk::Align::Center,
|
||||
// set_halign: gtk::Align::End,
|
||||
// set_label: "Update channel and system",
|
||||
// set_can_focus: false,
|
||||
// connect_clicked[sender] => move |_| {
|
||||
// sender.input(UpdatePageMsg::UpdateSystemAndChannels);
|
||||
// }
|
||||
// },
|
||||
// gtk::Button {
|
||||
// set_valign: gtk::Align::Center,
|
||||
// set_halign: gtk::Align::End,
|
||||
// set_label: "Update channel only",
|
||||
// set_can_focus: false,
|
||||
// connect_clicked[sender] => move |_| {
|
||||
// sender.input(UpdatePageMsg::UpdateChannels);
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_hexpand: true,
|
||||
@ -234,7 +231,7 @@ impl SimpleComponent for UpdatePageModel {
|
||||
set_halign: gtk::Align::End,
|
||||
set_hexpand: true,
|
||||
set_valign: gtk::Align::Center,
|
||||
set_label: "Update All",
|
||||
set_label: "Update",
|
||||
connect_clicked[sender] => move |_|{
|
||||
sender.input(UpdatePageMsg::UpdateSystem);
|
||||
},
|
||||
@ -282,9 +279,6 @@ impl SimpleComponent for UpdatePageModel {
|
||||
root: &Self::Root,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
let updatedialog = UpdateDialogModel::builder()
|
||||
.launch(initparams.window.upcast())
|
||||
.forward(sender.input_sender(), identity);
|
||||
let updateworker = UpdateAsyncHandler::builder()
|
||||
.detach_worker(UpdateAsyncHandlerInit { syspkgs: initparams.systype.clone(), userpkgs: initparams.usertype.clone() })
|
||||
.forward(sender.input_sender(), identity);
|
||||
@ -297,7 +291,6 @@ impl SimpleComponent for UpdatePageModel {
|
||||
updatesystemlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||
channelupdate: None,
|
||||
updatetracker: 0,
|
||||
updatedialog,
|
||||
updateworker,
|
||||
config,
|
||||
systype: initparams.systype,
|
||||
@ -329,13 +322,13 @@ impl SimpleComponent for UpdatePageModel {
|
||||
info!("UpdatePageMsg::Update");
|
||||
debug!("UPDATEUSERLIST: {:?}", updateuserlist);
|
||||
debug!("UPDATESYSTEMLIST: {:?}", updatesystemlist);
|
||||
self.channelupdate = match nix_data::cache::channel::uptodate() {
|
||||
Ok(x) => {
|
||||
x
|
||||
},
|
||||
Err(_) => None,
|
||||
};
|
||||
debug!("CHANNELUPDATE: {:?}", self.channelupdate);
|
||||
// self.channelupdate = match nix_data::cache::channel::uptodate() {
|
||||
// Ok(x) => {
|
||||
// x
|
||||
// },
|
||||
// Err(_) => None,
|
||||
// };
|
||||
// debug!("CHANNELUPDATE: {:?}", self.channelupdate);
|
||||
self.update_updatetracker(|_| ());
|
||||
let mut updateuserlist_guard = self.updateuserlist.guard();
|
||||
updateuserlist_guard.clear();
|
||||
@ -347,6 +340,16 @@ impl SimpleComponent for UpdatePageModel {
|
||||
for updatesystem in updatesystemlist {
|
||||
updatesystemlist_guard.push_back(updatesystem);
|
||||
}
|
||||
updatesystemlist_guard.push_back(UpdateItem {
|
||||
pkg: None,
|
||||
name: "NixOS".to_string(),
|
||||
pname: "nixos".to_string(),
|
||||
summary: None,
|
||||
icon: None,
|
||||
pkgtype: InstallType::System,
|
||||
verfrom: None,
|
||||
verto: None,
|
||||
});
|
||||
}
|
||||
UpdatePageMsg::OpenRow(row, pkgtype) => match pkgtype {
|
||||
InstallType::User => {
|
||||
@ -366,38 +369,36 @@ impl SimpleComponent for UpdatePageModel {
|
||||
}
|
||||
}
|
||||
},
|
||||
UpdatePageMsg::UpdateChannels => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating channels...")));
|
||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateChannels);
|
||||
}
|
||||
UpdatePageMsg::UpdateSystemAndChannels => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating system and channels...")));
|
||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateChannelsAndSystem);
|
||||
}
|
||||
// UpdatePageMsg::UpdateChannels => {
|
||||
// self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating channels...")));
|
||||
// self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateChannels);
|
||||
// }
|
||||
// UpdatePageMsg::UpdateSystemAndChannels => {
|
||||
// self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating system and channels...")));
|
||||
// self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateChannelsAndSystem);
|
||||
// }
|
||||
UpdatePageMsg::UpdateSystem => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating system...")));
|
||||
self.updateworker.emit(UpdateAsyncHandlerMsg::RebuildSystem);
|
||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateSystem);
|
||||
}
|
||||
UpdatePageMsg::UpdateUser(pkg) => {
|
||||
info!("UPDATE USER PKG: {}", pkg);
|
||||
warn!("unimplemented");
|
||||
}
|
||||
UpdatePageMsg::UpdateAllUser => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating all user packages...")));
|
||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateUserPkgs);
|
||||
}
|
||||
UpdatePageMsg::UpdateAll => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Show(String::from("Updating everything...")));
|
||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateAll);
|
||||
}
|
||||
UpdatePageMsg::DoneWorking => {
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishSuccess);
|
||||
sender.output(AppMsg::UpdateInstalledPkgs);
|
||||
}
|
||||
UpdatePageMsg::DoneLoading => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Done);
|
||||
}
|
||||
UpdatePageMsg::FailedWorking => {
|
||||
self.updatedialog.emit(UpdateDialogMsg::Failed);
|
||||
REBUILD_BROKER.send(RebuildMsg::FinishError(None));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
use nix_data::config::configfile::NixDataConfig;
|
||||
use relm4::*;
|
||||
use std::{error::Error, path::Path, process::Stdio};
|
||||
use std::{path::Path, process::Stdio};
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
use anyhow::Result;
|
||||
use log::*;
|
||||
|
||||
use crate::ui::{rebuild::RebuildMsg, window::REBUILD_BROKER};
|
||||
|
||||
use super::{
|
||||
updatepage::UpdatePageMsg,
|
||||
window::{SystemPkgs, UserPkgs},
|
||||
@ -25,8 +28,10 @@ pub enum UpdateAsyncHandlerMsg {
|
||||
UpdateConfig(NixDataConfig),
|
||||
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
||||
|
||||
UpdateChannels,
|
||||
UpdateChannelsAndSystem,
|
||||
// UpdateChannels,
|
||||
// UpdateChannelsAndSystem,
|
||||
|
||||
UpdateSystem,
|
||||
|
||||
RebuildSystem,
|
||||
UpdateUserPkgs,
|
||||
@ -79,35 +84,52 @@ impl Worker for UpdateAsyncHandler {
|
||||
self.syspkgs = syspkgs;
|
||||
self.userpkgs = userpkgs;
|
||||
}
|
||||
UpdateAsyncHandlerMsg::UpdateChannels => {
|
||||
// UpdateAsyncHandlerMsg::UpdateChannels => {
|
||||
// let systemconfig = self.systemconfig.clone();
|
||||
// let flakeargs = self.flakeargs.clone();
|
||||
// let syspkgs = self.syspkgs.clone();
|
||||
// relm4::spawn(async move {
|
||||
// let result = runcmd(NscCmd::Channel, systemconfig, flakeargs, syspkgs).await;
|
||||
// match result {
|
||||
// Ok(true) => {
|
||||
// sender.output(UpdatePageMsg::DoneWorking);
|
||||
// }
|
||||
// _ => {
|
||||
// warn!("UPDATE CHANNEL FAILED");
|
||||
// sender.output(UpdatePageMsg::FailedWorking);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// UpdateAsyncHandlerMsg::UpdateChannelsAndSystem => {
|
||||
// let systenconfig = self.systemconfig.clone();
|
||||
// let flakeargs = self.flakeargs.clone();
|
||||
// let syspkgs = self.syspkgs.clone();
|
||||
// relm4::spawn(async move {
|
||||
// let result = runcmd(NscCmd::All, systenconfig, flakeargs, syspkgs).await;
|
||||
// match result {
|
||||
// Ok(true) => {
|
||||
// sender.output(UpdatePageMsg::DoneWorking);
|
||||
// }
|
||||
// _ => {
|
||||
// warn!("UPDATE CHANNEL AND SYSTEM FAILED");
|
||||
// sender.output(UpdatePageMsg::FailedWorking);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
UpdateAsyncHandlerMsg::UpdateSystem => {
|
||||
let systemconfig = self.systemconfig.clone();
|
||||
let flakeargs = self.flakeargs.clone();
|
||||
let syspkgs = self.syspkgs.clone();
|
||||
relm4::spawn(async move {
|
||||
let result = runcmd(NscCmd::Channel, systemconfig, flakeargs, syspkgs).await;
|
||||
let result = runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs).await;
|
||||
match result {
|
||||
Ok(true) => {
|
||||
sender.output(UpdatePageMsg::DoneWorking);
|
||||
}
|
||||
_ => {
|
||||
warn!("UPDATE CHANNEL FAILED");
|
||||
sender.output(UpdatePageMsg::FailedWorking);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
UpdateAsyncHandlerMsg::UpdateChannelsAndSystem => {
|
||||
let systenconfig = self.systemconfig.clone();
|
||||
let flakeargs = self.flakeargs.clone();
|
||||
let syspkgs = self.syspkgs.clone();
|
||||
relm4::spawn(async move {
|
||||
let result = runcmd(NscCmd::All, systenconfig, flakeargs, syspkgs).await;
|
||||
match result {
|
||||
Ok(true) => {
|
||||
sender.output(UpdatePageMsg::DoneWorking);
|
||||
}
|
||||
_ => {
|
||||
warn!("UPDATE CHANNEL AND SYSTEM FAILED");
|
||||
warn!("UPDATE SYSTEM FAILED");
|
||||
sender.output(UpdatePageMsg::FailedWorking);
|
||||
}
|
||||
}
|
||||
@ -190,7 +212,7 @@ async fn runcmd(
|
||||
_systemconfig: Option<String>,
|
||||
flakeargs: Option<String>,
|
||||
syspkgs: SystemPkgs,
|
||||
) -> Result<bool, Box<dyn Error + Send + Sync>> {
|
||||
) -> Result<bool> {
|
||||
let exe = match std::env::current_exe() {
|
||||
Ok(mut e) => {
|
||||
e.pop(); // root/bin
|
||||
@ -255,6 +277,7 @@ async fn runcmd(
|
||||
.arg(flakepath)
|
||||
.arg("--")
|
||||
.arg("switch")
|
||||
.arg("--impure")
|
||||
.args(&rebuildargs)
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()?,
|
||||
@ -267,6 +290,7 @@ async fn runcmd(
|
||||
|
||||
let mut lines = reader.lines();
|
||||
while let Ok(Some(line)) = lines.next_line().await {
|
||||
REBUILD_BROKER.send(RebuildMsg::UpdateText(line.to_string()));
|
||||
trace!("CAUGHT REBUILD LINE: {}", line);
|
||||
}
|
||||
if cmd.wait().await?.success() {
|
||||
@ -276,7 +300,7 @@ async fn runcmd(
|
||||
}
|
||||
}
|
||||
|
||||
async fn updateenv() -> Result<bool, Box<dyn Error + Send + Sync>> {
|
||||
async fn updateenv() -> Result<bool> {
|
||||
let mut cmd = tokio::process::Command::new("nix-env")
|
||||
.arg("-u")
|
||||
.stderr(Stdio::piped())
|
||||
@ -287,6 +311,7 @@ async fn updateenv() -> Result<bool, Box<dyn Error + Send + Sync>> {
|
||||
|
||||
let mut lines = reader.lines();
|
||||
while let Ok(Some(line)) = lines.next_line().await {
|
||||
REBUILD_BROKER.send(RebuildMsg::UpdateText(line.to_string()));
|
||||
trace!("CAUGHT NIXENV LINE: {}", line);
|
||||
}
|
||||
if cmd.wait().await?.success() {
|
||||
@ -296,7 +321,7 @@ async fn updateenv() -> Result<bool, Box<dyn Error + Send + Sync>> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn updateprofile() -> Result<bool, Box<dyn Error + Send + Sync>> {
|
||||
async fn updateprofile() -> Result<bool> {
|
||||
let mut cmd = tokio::process::Command::new("nix")
|
||||
.arg("profile")
|
||||
.arg("upgrade")
|
||||
@ -311,6 +336,7 @@ async fn updateprofile() -> Result<bool, Box<dyn Error + Send + Sync>> {
|
||||
|
||||
let mut lines = reader.lines();
|
||||
while let Ok(Some(line)) = lines.next_line().await {
|
||||
REBUILD_BROKER.send(RebuildMsg::UpdateText(line.to_string()));
|
||||
trace!("CAUGHT NIX PROFILE LINE: {}", line);
|
||||
}
|
||||
if cmd.wait().await?.success() {
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
config::{editconfig, getconfig},
|
||||
packages::{AppData, LicenseEnum, PkgMaintainer, Platform},
|
||||
},
|
||||
ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg},
|
||||
ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg, rebuild::RebuildMsg},
|
||||
APPINFO,
|
||||
};
|
||||
use adw::prelude::*;
|
||||
@ -32,9 +32,11 @@ use super::{
|
||||
searchpage::{SearchItem, SearchPageModel, SearchPageMsg},
|
||||
updatepage::{UpdateItem, UpdatePageInit, UpdatePageModel, UpdatePageMsg},
|
||||
welcome::WelcomeModel,
|
||||
windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg},
|
||||
windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg}, rebuild::RebuildModel,
|
||||
};
|
||||
|
||||
pub static REBUILD_BROKER: MessageBroker<RebuildModel> = MessageBroker::new();
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Page {
|
||||
FrontPage,
|
||||
@ -109,6 +111,8 @@ pub struct AppModel {
|
||||
updatepage: Controller<UpdatePageModel>,
|
||||
viewstack: adw::ViewStack,
|
||||
installedpagebusy: Vec<(String, InstallType)>,
|
||||
#[tracker::no_eq]
|
||||
rebuild: Controller<RebuildModel>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -146,8 +150,8 @@ pub enum AppMsg {
|
||||
RemoveInstalledBusy(WorkPkg),
|
||||
OpenCategoryPage(PkgCategory),
|
||||
LoadCategory(PkgCategory),
|
||||
|
||||
UpdateRecPkgs(Vec<String>),
|
||||
SetDarkMode(bool),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@ -490,6 +494,9 @@ impl Component for AppModel {
|
||||
config: config.clone(),
|
||||
})
|
||||
.forward(sender.input_sender(), identity);
|
||||
let rebuild = RebuildModel::builder()
|
||||
.launch_with_broker(root.clone().upcast(), &REBUILD_BROKER)
|
||||
.forward(sender.input_sender(), identity);
|
||||
let viewstack = adw::ViewStack::new();
|
||||
|
||||
let model = AppModel {
|
||||
@ -523,9 +530,18 @@ impl Component for AppModel {
|
||||
updatepage,
|
||||
viewstack,
|
||||
installedpagebusy: vec![],
|
||||
rebuild,
|
||||
tracker: 0,
|
||||
};
|
||||
|
||||
{
|
||||
let sender = sender.clone();
|
||||
adw::StyleManager::default()
|
||||
.connect_dark_notify(move |x| sender.input(AppMsg::SetDarkMode(x.is_dark())));
|
||||
}
|
||||
|
||||
sender.input(AppMsg::SetDarkMode(adw::StyleManager::default().is_dark()));
|
||||
|
||||
if welcome {
|
||||
let welcomepage = WelcomeModel::builder()
|
||||
.launch(root.clone().upcast())
|
||||
@ -582,6 +598,7 @@ impl Component for AppModel {
|
||||
frontvs.set_icon_name(Some("nsc-home-symbolic"));
|
||||
installedvs.set_icon_name(Some("nsc-installed-symbolic"));
|
||||
updatesvs.set_icon_name(Some("nsc-update-symbolic"));
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
@ -1803,6 +1820,11 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute =
|
||||
AppAsyncMsg::LoadCategory(category, catrec, catall)
|
||||
});
|
||||
}
|
||||
AppMsg::SetDarkMode(dark) => {
|
||||
info!("AppMsg::SetDarkMode({})", dark);
|
||||
let scheme = if dark { "Adwaita-dark" } else { "Adwaita" };
|
||||
self.rebuild.emit(RebuildMsg::SetScheme(scheme.to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user