mirror of
https://github.com/snowfallorg/nix-software-center.git
synced 2024-10-26 23:19:24 +03:00
Add unavailable package dialog
This commit is contained in:
parent
ceb00abc4c
commit
b25fd4e7b9
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -1592,9 +1592,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.10"
|
version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9"
|
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1617,7 +1617,7 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nix-data"
|
name = "nix-data"
|
||||||
version = "0.0.2"
|
version = "0.0.2"
|
||||||
source = "git+https://github.com/snowflakelinux/nix-data#33479e595f14142f15fb6ec29cc585352c2c7703"
|
source = "git+https://github.com/snowflakelinux/nix-data#315d3efee6860cdc48e514ac1fa288196312a4f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"csv",
|
"csv",
|
||||||
@ -1742,9 +1742,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.1"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -20,7 +20,7 @@ pkgs.stdenv.mkDerivation rec {
|
|||||||
cargoDeps = pkgs.rustPlatform.fetchCargoTarball {
|
cargoDeps = pkgs.rustPlatform.fetchCargoTarball {
|
||||||
inherit src;
|
inherit src;
|
||||||
name = "${pname}-${version}";
|
name = "${pname}-${version}";
|
||||||
hash = "sha256-CRw/T0TAgW+81C3966PAEpDHJotSbOHkAqhotY1sozM=";
|
hash = "sha256-yChtK86/onSI2JQaQkBwwVzijGTEyc6vQbCUmgWb3u8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clap::{self, FromArgMatches, Subcommand};
|
use clap::{self, FromArgMatches, Subcommand};
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
fs::{File, self},
|
fs::{self, File},
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
@ -23,6 +23,12 @@ enum SubCommands {
|
|||||||
/// Whether to rebuild the system after updating channels
|
/// Whether to rebuild the system after updating channels
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
rebuild: bool,
|
rebuild: bool,
|
||||||
|
/// Update file
|
||||||
|
#[arg(short, long)]
|
||||||
|
update: bool,
|
||||||
|
/// Write stdin to file in path output
|
||||||
|
#[arg(short, long)]
|
||||||
|
output: String,
|
||||||
/// Run `nixos-rebuild` with the given arguments
|
/// Run `nixos-rebuild` with the given arguments
|
||||||
arguments: Vec<String>,
|
arguments: Vec<String>,
|
||||||
},
|
},
|
||||||
@ -33,6 +39,12 @@ enum SubCommands {
|
|||||||
/// Path to the flake file
|
/// Path to the flake file
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
flakepath: String,
|
flakepath: String,
|
||||||
|
/// Update file
|
||||||
|
#[arg(short, long)]
|
||||||
|
update: bool,
|
||||||
|
/// Write stdin to file in path output
|
||||||
|
#[arg(short, long)]
|
||||||
|
output: String,
|
||||||
/// Run `nixos-rebuild` with the given arguments
|
/// Run `nixos-rebuild` with the given arguments
|
||||||
arguments: Vec<String>,
|
arguments: Vec<String>,
|
||||||
},
|
},
|
||||||
@ -81,7 +93,18 @@ fn main() {
|
|||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SubCommands::Channel { rebuild: dorebuild, arguments } => {
|
SubCommands::Channel {
|
||||||
|
rebuild: dorebuild,
|
||||||
|
update,
|
||||||
|
output,
|
||||||
|
arguments,
|
||||||
|
} => {
|
||||||
|
if update {
|
||||||
|
if let Err(e) = write_file(&output) {
|
||||||
|
eprintln!("{}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
match channel() {
|
match channel() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if dorebuild {
|
if dorebuild {
|
||||||
@ -93,14 +116,26 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
SubCommands::Flake { rebuild: dorebuild, flakepath, arguments } => {
|
SubCommands::Flake {
|
||||||
|
rebuild: dorebuild,
|
||||||
|
flakepath,
|
||||||
|
update,
|
||||||
|
output,
|
||||||
|
arguments,
|
||||||
|
} => {
|
||||||
|
if update {
|
||||||
|
if let Err(e) = write_file(&output) {
|
||||||
|
eprintln!("{}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
match flake(&flakepath) {
|
match flake(&flakepath) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if dorebuild {
|
if dorebuild {
|
||||||
@ -112,7 +147,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
@ -132,9 +167,7 @@ fn write_file(path: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rebuild(args: Vec<String>) -> Result<(), Box<dyn Error>> {
|
fn rebuild(args: Vec<String>) -> Result<(), Box<dyn Error>> {
|
||||||
let mut cmd = Command::new("nixos-rebuild")
|
let mut cmd = Command::new("nixos-rebuild").args(args).spawn()?;
|
||||||
.args(args)
|
|
||||||
.spawn()?;
|
|
||||||
let x = cmd.wait()?;
|
let x = cmd.wait()?;
|
||||||
if x.success() {
|
if x.success() {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -148,9 +181,7 @@ fn rebuild(args: Vec<String>) -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn channel() -> Result<(), Box<dyn Error>> {
|
fn channel() -> Result<(), Box<dyn Error>> {
|
||||||
let mut cmd = Command::new("nix-channel")
|
let mut cmd = Command::new("nix-channel").arg("--update").spawn()?;
|
||||||
.arg("--update")
|
|
||||||
.spawn()?;
|
|
||||||
let x = cmd.wait()?;
|
let x = cmd.wait()?;
|
||||||
if x.success() {
|
if x.success() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -135,6 +135,7 @@ impl Worker for InstallAsyncHandler {
|
|||||||
.arg("profile")
|
.arg("profile")
|
||||||
.arg("install")
|
.arg("install")
|
||||||
.arg(format!("nixpkgs#{}", work.pkg))
|
.arg(format!("nixpkgs#{}", work.pkg))
|
||||||
|
.arg("--impure")
|
||||||
.kill_on_drop(true)
|
.kill_on_drop(true)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
|
@ -10,6 +10,7 @@ pub mod preferencespage;
|
|||||||
pub mod rebuild;
|
pub mod rebuild;
|
||||||
pub mod screenshotfactory;
|
pub mod screenshotfactory;
|
||||||
pub mod searchpage;
|
pub mod searchpage;
|
||||||
|
pub mod unavailabledialog;
|
||||||
pub mod updatepage;
|
pub mod updatepage;
|
||||||
pub mod updateworker;
|
pub mod updateworker;
|
||||||
pub mod welcome;
|
pub mod welcome;
|
||||||
|
264
src/ui/unavailabledialog.rs
Normal file
264
src/ui/unavailabledialog.rs
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use gtk::pango;
|
||||||
|
use log::*;
|
||||||
|
use relm4::{*, prelude::*, factory::*};
|
||||||
|
use adw::prelude::*;
|
||||||
|
use crate::{APPINFO, ui::{window::REBUILD_BROKER, rebuild::RebuildMsg}};
|
||||||
|
|
||||||
|
use super::updatepage::{UpdatePageMsg, UpdateType};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct UnavailableDialogModel {
|
||||||
|
hidden: bool,
|
||||||
|
unavailableuseritems: FactoryVecDeque<UnavailableItemModel>,
|
||||||
|
unavailablesysitems: FactoryVecDeque<UnavailableItemModel>,
|
||||||
|
updatetype: UpdateType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UnavailableDialogMsg {
|
||||||
|
Show(Vec<UnavailableItemModel>, Vec<UnavailableItemModel>, UpdateType),
|
||||||
|
Close,
|
||||||
|
Continue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub)]
|
||||||
|
impl SimpleComponent for UnavailableDialogModel {
|
||||||
|
type Init = gtk::Window;
|
||||||
|
type Input = UnavailableDialogMsg;
|
||||||
|
type Output = UpdatePageMsg;
|
||||||
|
type Widgets = UnavailableDialogWidgets;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
dialog = adw::MessageDialog {
|
||||||
|
#[watch]
|
||||||
|
set_visible: !model.hidden,
|
||||||
|
set_transient_for: Some(&parent_window),
|
||||||
|
set_modal: true,
|
||||||
|
set_heading: Some("Some packages are unavailable!"),
|
||||||
|
set_body: "If you continue this update, some packages will be removed",
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_extra_child = >k::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 20,
|
||||||
|
adw::PreferencesGroup {
|
||||||
|
#[watch]
|
||||||
|
set_visible: !model.unavailableuseritems.is_empty(),
|
||||||
|
set_title: "User Packages",
|
||||||
|
#[local_ref]
|
||||||
|
unavailableuserlist -> gtk::ListBox {
|
||||||
|
add_css_class: "boxed-list",
|
||||||
|
set_selection_mode: gtk::SelectionMode::None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
adw::PreferencesGroup {
|
||||||
|
#[watch]
|
||||||
|
set_visible: !model.unavailablesysitems.is_empty(),
|
||||||
|
set_title: "System Packages",
|
||||||
|
#[local_ref]
|
||||||
|
unavailablesyslist -> gtk::ListBox {
|
||||||
|
add_css_class: "boxed-list",
|
||||||
|
set_selection_mode: gtk::SelectionMode::None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
add_response: ("cancel", "Cancel"),
|
||||||
|
add_response: ("continue", "Continue"),
|
||||||
|
set_response_appearance: ("continue", adw::ResponseAppearance::Destructive),
|
||||||
|
connect_close_request => |_| {
|
||||||
|
gtk::Inhibit(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
parent_window: Self::Init,
|
||||||
|
root: &Self::Root,
|
||||||
|
sender: ComponentSender<Self>,
|
||||||
|
) -> ComponentParts<Self> {
|
||||||
|
|
||||||
|
let model = UnavailableDialogModel {
|
||||||
|
unavailableuseritems: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
|
unavailablesysitems: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
|
updatetype: UpdateType::All,
|
||||||
|
hidden: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let unavailableuserlist = model.unavailableuseritems.widget();
|
||||||
|
let unavailablesyslist = model.unavailablesysitems.widget();
|
||||||
|
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
widgets.dialog.connect_response(None, move |_, resp| {
|
||||||
|
match resp {
|
||||||
|
"cancel" => {
|
||||||
|
REBUILD_BROKER.send(RebuildMsg::Close);
|
||||||
|
debug!("Response: cancel")
|
||||||
|
},
|
||||||
|
"continue" => {
|
||||||
|
sender.input(UnavailableDialogMsg::Continue);
|
||||||
|
debug!("Response: continue")
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ComponentParts { model, widgets }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||||
|
match msg {
|
||||||
|
UnavailableDialogMsg::Show(useritems, sysitems, updatetype) => {
|
||||||
|
self.updatetype = updatetype;
|
||||||
|
let mut unavailableuseritems_guard = self.unavailableuseritems.guard();
|
||||||
|
unavailableuseritems_guard.clear();
|
||||||
|
for item in useritems {
|
||||||
|
unavailableuseritems_guard.push_back(item);
|
||||||
|
}
|
||||||
|
let mut unavailablesysitems_guard = self.unavailablesysitems.guard();
|
||||||
|
for item in sysitems {
|
||||||
|
unavailablesysitems_guard.push_back(item);
|
||||||
|
}
|
||||||
|
self.hidden = false;
|
||||||
|
}
|
||||||
|
UnavailableDialogMsg::Close => {
|
||||||
|
info!("UpdateDialogMsg::Close");
|
||||||
|
let mut unavailableuseritems_guard = self.unavailableuseritems.guard();
|
||||||
|
let mut unavailablesysitems_guard = self.unavailablesysitems.guard();
|
||||||
|
unavailableuseritems_guard.clear();
|
||||||
|
unavailablesysitems_guard.clear();
|
||||||
|
self.hidden = true;
|
||||||
|
}
|
||||||
|
UnavailableDialogMsg::Continue => {
|
||||||
|
match self.updatetype {
|
||||||
|
UpdateType::User => {
|
||||||
|
sender.output(UpdatePageMsg::UpdateAllUserRm(self.unavailableuseritems.iter().map(|x| x.pkg.to_string()).collect()));
|
||||||
|
}
|
||||||
|
UpdateType::System => {
|
||||||
|
sender.output(UpdatePageMsg::UpdateSystemRm(self.unavailablesysitems.iter().map(|x| x.pkg.to_string()).collect()));
|
||||||
|
}
|
||||||
|
UpdateType::All => {
|
||||||
|
sender.output(UpdatePageMsg::UpdateAllRm(self.unavailableuseritems.iter().map(|x| x.pkg.to_string()).collect(), self.unavailablesysitems.iter().map(|x| x.pkg.to_string()).collect()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sender.input(UnavailableDialogMsg::Close)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
|
pub struct UnavailableItemModel {
|
||||||
|
pub name: String,
|
||||||
|
pub pkg: String,
|
||||||
|
pub pname: String,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UnavailableItemMsg {}
|
||||||
|
|
||||||
|
#[relm4::factory(pub)]
|
||||||
|
impl FactoryComponent for UnavailableItemModel {
|
||||||
|
type CommandOutput = ();
|
||||||
|
type Init = UnavailableItemModel;
|
||||||
|
type Input = ();
|
||||||
|
type Output = UnavailableItemMsg;
|
||||||
|
type Widgets = UnavailableItemWidgets;
|
||||||
|
type ParentWidget = adw::gtk::ListBox;
|
||||||
|
type ParentInput = UnavailableDialogMsg;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
adw::PreferencesRow {
|
||||||
|
set_activatable: 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,
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_child = if self.icon.is_some() {
|
||||||
|
gtk::Image {
|
||||||
|
add_css_class: "icon-dropshadow",
|
||||||
|
set_halign: gtk::Align::Start,
|
||||||
|
set_from_file: {
|
||||||
|
if let Some(i) = &self.icon {
|
||||||
|
let iconpath = format!("{}/icons/nixos/128x128/{}", APPINFO, i);
|
||||||
|
let iconpath64 = format!("{}/icons/nixos/64x64/{}", APPINFO, i);
|
||||||
|
if Path::new(&iconpath).is_file() {
|
||||||
|
Some(iconpath)
|
||||||
|
} else if Path::new(&iconpath64).is_file() {
|
||||||
|
Some(iconpath64)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set_pixel_size: 64,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gtk::Image {
|
||||||
|
add_css_class: "icon-dropshadow",
|
||||||
|
set_halign: gtk::Align::Start,
|
||||||
|
set_icon_name: Some("package-x-generic"),
|
||||||
|
set_pixel_size: 64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_halign: gtk::Align::Fill,
|
||||||
|
set_valign: gtk::Align::Center,
|
||||||
|
set_hexpand: true,
|
||||||
|
set_spacing: 20,
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_halign: gtk::Align::Fill,
|
||||||
|
set_valign: gtk::Align::Center,
|
||||||
|
set_spacing: 2,
|
||||||
|
gtk::Label {
|
||||||
|
set_halign: gtk::Align::Start,
|
||||||
|
set_label: self.name.as_str(),
|
||||||
|
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: self.pkg.as_str(),
|
||||||
|
set_ellipsize: pango::EllipsizeMode::End,
|
||||||
|
set_lines: 1,
|
||||||
|
set_wrap: true,
|
||||||
|
set_max_width_chars: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gtk::Label {
|
||||||
|
set_halign: gtk::Align::Center,
|
||||||
|
set_hexpand: true,
|
||||||
|
set_label: self.message.as_str(),
|
||||||
|
set_wrap: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_model(
|
||||||
|
init: Self::Init,
|
||||||
|
_index: &DynamicIndex,
|
||||||
|
_sender: FactoryComponentSender<Self>,
|
||||||
|
) -> Self {
|
||||||
|
init
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
use crate::APPINFO;
|
use crate::{APPINFO, ui::unavailabledialog::UnavailableDialogModel};
|
||||||
|
|
||||||
use super::{pkgpage::InstallType, window::*, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}, rebuild::RebuildMsg};
|
use super::{pkgpage::InstallType, window::*, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}, rebuild::RebuildMsg};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use nix_data::config::configfile::NixDataConfig;
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::{factory::*, gtk::pango, *};
|
use relm4::{factory::*, gtk::pango, *};
|
||||||
use std::{path::Path, convert::identity};
|
use std::{path::Path, convert::identity, collections::HashMap};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
|
pub static UNAVAILABLE_BROKER: MessageBroker<UnavailableDialogModel> = MessageBroker::new();
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UpdatePageModel {
|
pub struct UpdatePageModel {
|
||||||
@ -21,6 +23,8 @@ pub struct UpdatePageModel {
|
|||||||
systype: SystemPkgs,
|
systype: SystemPkgs,
|
||||||
usertype: UserPkgs,
|
usertype: UserPkgs,
|
||||||
updatetracker: u8,
|
updatetracker: u8,
|
||||||
|
#[tracker::no_eq]
|
||||||
|
unavailabledialog: Controller<UnavailableDialogModel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -30,15 +34,25 @@ pub enum UpdatePageMsg {
|
|||||||
Update(Vec<UpdateItem>, Vec<UpdateItem>),
|
Update(Vec<UpdateItem>, Vec<UpdateItem>),
|
||||||
OpenRow(usize, InstallType),
|
OpenRow(usize, InstallType),
|
||||||
UpdateSystem,
|
UpdateSystem,
|
||||||
|
UpdateSystemRm(Vec<String>),
|
||||||
UpdateAllUser,
|
UpdateAllUser,
|
||||||
|
UpdateAllUserRm(Vec<String>),
|
||||||
UpdateUser(String),
|
UpdateUser(String),
|
||||||
// UpdateChannels,
|
// UpdateChannels,
|
||||||
// UpdateSystemAndChannels,
|
// UpdateSystemAndChannels,
|
||||||
UpdateAll,
|
UpdateAll,
|
||||||
|
UpdateAllRm(Vec<String>, Vec<String>),
|
||||||
DoneWorking,
|
DoneWorking,
|
||||||
FailedWorking,
|
FailedWorking,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UpdateType {
|
||||||
|
System,
|
||||||
|
User,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UpdatePageInit {
|
pub struct UpdatePageInit {
|
||||||
pub window: gtk::Window,
|
pub window: gtk::Window,
|
||||||
pub systype: SystemPkgs,
|
pub systype: SystemPkgs,
|
||||||
@ -84,101 +98,6 @@ 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 {
|
gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
set_hexpand: true,
|
set_hexpand: true,
|
||||||
@ -283,6 +202,10 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
.detach_worker(UpdateAsyncHandlerInit { syspkgs: initparams.systype.clone(), userpkgs: initparams.usertype.clone() })
|
.detach_worker(UpdateAsyncHandlerInit { syspkgs: initparams.systype.clone(), userpkgs: initparams.usertype.clone() })
|
||||||
.forward(sender.input_sender(), identity);
|
.forward(sender.input_sender(), identity);
|
||||||
|
|
||||||
|
let unavailabledialog = UnavailableDialogModel::builder()
|
||||||
|
.launch_with_broker(initparams.window.clone(), &UNAVAILABLE_BROKER)
|
||||||
|
.forward(sender.input_sender(), identity);
|
||||||
|
|
||||||
let config = initparams.config;
|
let config = initparams.config;
|
||||||
updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(config.clone()));
|
updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(config.clone()));
|
||||||
|
|
||||||
@ -295,6 +218,7 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
config,
|
config,
|
||||||
systype: initparams.systype,
|
systype: initparams.systype,
|
||||||
usertype: initparams.usertype,
|
usertype: initparams.usertype,
|
||||||
|
unavailabledialog,
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -322,13 +246,6 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
info!("UpdatePageMsg::Update");
|
info!("UpdatePageMsg::Update");
|
||||||
debug!("UPDATEUSERLIST: {:?}", updateuserlist);
|
debug!("UPDATEUSERLIST: {:?}", updateuserlist);
|
||||||
debug!("UPDATESYSTEMLIST: {:?}", updatesystemlist);
|
debug!("UPDATESYSTEMLIST: {:?}", updatesystemlist);
|
||||||
// self.channelupdate = match nix_data::cache::channel::uptodate() {
|
|
||||||
// Ok(x) => {
|
|
||||||
// x
|
|
||||||
// },
|
|
||||||
// Err(_) => None,
|
|
||||||
// };
|
|
||||||
// debug!("CHANNELUPDATE: {:?}", self.channelupdate);
|
|
||||||
self.update_updatetracker(|_| ());
|
self.update_updatetracker(|_| ());
|
||||||
let mut updateuserlist_guard = self.updateuserlist.guard();
|
let mut updateuserlist_guard = self.updateuserlist.guard();
|
||||||
updateuserlist_guard.clear();
|
updateuserlist_guard.clear();
|
||||||
@ -340,16 +257,6 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
for updatesystem in updatesystemlist {
|
for updatesystem in updatesystemlist {
|
||||||
updatesystemlist_guard.push_back(updatesystem);
|
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 {
|
UpdatePageMsg::OpenRow(row, pkgtype) => match pkgtype {
|
||||||
InstallType::User => {
|
InstallType::User => {
|
||||||
@ -369,17 +276,33 @@ 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::UpdateSystem => {
|
UpdatePageMsg::UpdateSystem => {
|
||||||
|
let systype = self.systype.clone();
|
||||||
|
let systemconfig = self.config.systemconfig.clone();
|
||||||
|
let workersender = self.updateworker.sender().clone();
|
||||||
|
let output = sender.output_sender().clone();
|
||||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateSystem);
|
relm4::spawn(async move {
|
||||||
|
let uninstallsys = match systype {
|
||||||
|
SystemPkgs::Legacy => {
|
||||||
|
nix_data::cache::channel::unavailablepkgs(&[&systemconfig.unwrap()]).await.unwrap_or_default()
|
||||||
|
}
|
||||||
|
SystemPkgs::Flake => {
|
||||||
|
nix_data::cache::flakes::unavailablepkgs(&[&systemconfig.unwrap()]).await.unwrap_or_default()
|
||||||
|
}
|
||||||
|
_ => HashMap::new(),
|
||||||
|
};
|
||||||
|
if uninstallsys.is_empty() {
|
||||||
|
workersender.send(UpdateAsyncHandlerMsg::UpdateSystem);
|
||||||
|
} else {
|
||||||
|
warn!("Uninstalling unavailable packages: {:?}", uninstallsys);
|
||||||
|
output.send(AppMsg::GetUnavailableItems(HashMap::new(), uninstallsys, UpdateType::System));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
UpdatePageMsg::UpdateSystemRm(pkgs) => {
|
||||||
|
info!("UpdatePageMsg::UpdateSystemRm({:?})", pkgs);
|
||||||
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateSystemRemove(pkgs));
|
||||||
}
|
}
|
||||||
UpdatePageMsg::UpdateUser(pkg) => {
|
UpdatePageMsg::UpdateUser(pkg) => {
|
||||||
info!("UPDATE USER PKG: {}", pkg);
|
info!("UPDATE USER PKG: {}", pkg);
|
||||||
@ -387,11 +310,62 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
}
|
}
|
||||||
UpdatePageMsg::UpdateAllUser => {
|
UpdatePageMsg::UpdateAllUser => {
|
||||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||||
|
if self.usertype == UserPkgs::Profile {
|
||||||
|
let workersender = self.updateworker.sender().clone();
|
||||||
|
let output = sender.output_sender().clone();
|
||||||
|
relm4::spawn(async move {
|
||||||
|
let uninstalluser = nix_data::cache::profile::unavailablepkgs().await.unwrap_or_default();
|
||||||
|
if uninstalluser.is_empty() {
|
||||||
|
workersender.send(UpdateAsyncHandlerMsg::UpdateUserPkgs);
|
||||||
|
} else {
|
||||||
|
warn!("Uninstalling unavailable packages: {:?}", uninstalluser);
|
||||||
|
output.send(AppMsg::GetUnavailableItems(uninstalluser, HashMap::new(), UpdateType::User));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateUserPkgs);
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateUserPkgs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
UpdatePageMsg::UpdateAllUserRm(pkgs) => {
|
||||||
|
info!("UpdatePageMsg::UpdateAllUserRm({:?})", pkgs);
|
||||||
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateUserPkgsRemove(pkgs));
|
||||||
|
}
|
||||||
UpdatePageMsg::UpdateAll => {
|
UpdatePageMsg::UpdateAll => {
|
||||||
|
info!("UpdatePageMsg::UpdateAll");
|
||||||
|
let systype = self.systype.clone();
|
||||||
|
let usertype = self.usertype.clone();
|
||||||
|
let systemconfig = self.config.systemconfig.clone();
|
||||||
|
let workersender = self.updateworker.sender().clone();
|
||||||
|
let output = sender.output_sender().clone();
|
||||||
REBUILD_BROKER.send(RebuildMsg::Show);
|
REBUILD_BROKER.send(RebuildMsg::Show);
|
||||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateAll);
|
relm4::spawn(async move {
|
||||||
|
let uninstallsys = match systype {
|
||||||
|
SystemPkgs::Legacy => {
|
||||||
|
nix_data::cache::channel::unavailablepkgs(&[&systemconfig.unwrap()]).await.unwrap_or_default()
|
||||||
|
}
|
||||||
|
SystemPkgs::Flake => {
|
||||||
|
nix_data::cache::flakes::unavailablepkgs(&[&systemconfig.unwrap()]).await.unwrap_or_default()
|
||||||
|
}
|
||||||
|
_ => HashMap::new(),
|
||||||
|
};
|
||||||
|
let uninstalluser = if usertype == UserPkgs::Profile {
|
||||||
|
nix_data::cache::profile::unavailablepkgs().await.unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
HashMap::new()
|
||||||
|
};
|
||||||
|
if uninstallsys.is_empty() && uninstalluser.is_empty() {
|
||||||
|
workersender.send(UpdateAsyncHandlerMsg::UpdateAll);
|
||||||
|
} else {
|
||||||
|
warn!("Uninstalling unavailable user packages: {:?}", uninstalluser);
|
||||||
|
warn!("Uninstalling unavailable system packages: {:?}", uninstallsys);
|
||||||
|
output.send(AppMsg::GetUnavailableItems(uninstalluser, uninstallsys, UpdateType::All));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
UpdatePageMsg::UpdateAllRm(userpkgs, syspkgs) => {
|
||||||
|
info!("UpdatePageMsg::UpdateAllRm({:?}, {:?})", userpkgs, syspkgs);
|
||||||
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateAllRemove(userpkgs, syspkgs));
|
||||||
}
|
}
|
||||||
UpdatePageMsg::DoneWorking => {
|
UpdatePageMsg::DoneWorking => {
|
||||||
REBUILD_BROKER.send(RebuildMsg::FinishSuccess);
|
REBUILD_BROKER.send(RebuildMsg::FinishSuccess);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use log::*;
|
||||||
use nix_data::config::configfile::NixDataConfig;
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
use std::{path::Path, process::Stdio};
|
use std::{fs, path::Path, process::Stdio};
|
||||||
use tokio::io::AsyncBufReadExt;
|
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
|
||||||
use anyhow::Result;
|
|
||||||
use log::*;
|
|
||||||
|
|
||||||
use crate::ui::{rebuild::RebuildMsg, window::REBUILD_BROKER};
|
use crate::ui::{rebuild::RebuildMsg, window::REBUILD_BROKER};
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ use super::{
|
|||||||
pub struct UpdateAsyncHandler {
|
pub struct UpdateAsyncHandler {
|
||||||
#[tracker::no_eq]
|
#[tracker::no_eq]
|
||||||
process: Option<JoinHandle<()>>,
|
process: Option<JoinHandle<()>>,
|
||||||
systemconfig: Option<String>,
|
systemconfig: String,
|
||||||
flakeargs: Option<String>,
|
flakeargs: Option<String>,
|
||||||
syspkgs: SystemPkgs,
|
syspkgs: SystemPkgs,
|
||||||
userpkgs: UserPkgs,
|
userpkgs: UserPkgs,
|
||||||
@ -30,13 +30,15 @@ pub enum UpdateAsyncHandlerMsg {
|
|||||||
|
|
||||||
// UpdateChannels,
|
// UpdateChannels,
|
||||||
// UpdateChannelsAndSystem,
|
// UpdateChannelsAndSystem,
|
||||||
|
|
||||||
UpdateSystem,
|
UpdateSystem,
|
||||||
|
UpdateSystemRemove(Vec<String>),
|
||||||
|
|
||||||
RebuildSystem,
|
RebuildSystem,
|
||||||
UpdateUserPkgs,
|
UpdateUserPkgs,
|
||||||
|
UpdateUserPkgsRemove(Vec<String>),
|
||||||
|
|
||||||
UpdateAll,
|
UpdateAll,
|
||||||
|
UpdateAllRemove(Vec<String>, Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NscCmd {
|
enum NscCmd {
|
||||||
@ -58,7 +60,7 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
fn init(params: Self::Init, _sender: relm4::ComponentSender<Self>) -> Self {
|
fn init(params: Self::Init, _sender: relm4::ComponentSender<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
process: None,
|
process: None,
|
||||||
systemconfig: None,
|
systemconfig: String::new(),
|
||||||
flakeargs: None,
|
flakeargs: None,
|
||||||
syspkgs: params.syspkgs,
|
syspkgs: params.syspkgs,
|
||||||
userpkgs: params.userpkgs,
|
userpkgs: params.userpkgs,
|
||||||
@ -69,7 +71,7 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||||
match msg {
|
match msg {
|
||||||
UpdateAsyncHandlerMsg::UpdateConfig(config) => {
|
UpdateAsyncHandlerMsg::UpdateConfig(config) => {
|
||||||
self.systemconfig = config.systemconfig;
|
self.systemconfig = config.systemconfig.unwrap_or_default();
|
||||||
self.flakeargs = if let Some(flake) = config.flake {
|
self.flakeargs = if let Some(flake) = config.flake {
|
||||||
if let Some(flakearg) = config.flakearg {
|
if let Some(flakearg) = config.flakearg {
|
||||||
Some(format!("{}#{}", flake, flakearg))
|
Some(format!("{}#{}", flake, flakearg))
|
||||||
@ -84,46 +86,30 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
self.syspkgs = syspkgs;
|
self.syspkgs = syspkgs;
|
||||||
self.userpkgs = userpkgs;
|
self.userpkgs = userpkgs;
|
||||||
}
|
}
|
||||||
// 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 => {
|
UpdateAsyncHandlerMsg::UpdateSystem => {
|
||||||
let systemconfig = self.systemconfig.clone();
|
let systemconfig = self.systemconfig.clone();
|
||||||
let flakeargs = self.flakeargs.clone();
|
let flakeargs = self.flakeargs.clone();
|
||||||
let syspkgs = self.syspkgs.clone();
|
let syspkgs = self.syspkgs.clone();
|
||||||
relm4::spawn(async move {
|
relm4::spawn(async move {
|
||||||
let result = runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs).await;
|
let result = runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs, None).await;
|
||||||
|
match result {
|
||||||
|
Ok(true) => {
|
||||||
|
sender.output(UpdatePageMsg::DoneWorking);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("UPDATE SYSTEM FAILED");
|
||||||
|
sender.output(UpdatePageMsg::FailedWorking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
UpdateAsyncHandlerMsg::UpdateSystemRemove(pkgs) => {
|
||||||
|
let systemconfig = self.systemconfig.clone();
|
||||||
|
let flakeargs = self.flakeargs.clone();
|
||||||
|
let syspkgs = self.syspkgs.clone();
|
||||||
|
relm4::spawn(async move {
|
||||||
|
let result =
|
||||||
|
runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs, Some(pkgs)).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
sender.output(UpdatePageMsg::DoneWorking);
|
sender.output(UpdatePageMsg::DoneWorking);
|
||||||
@ -141,8 +127,12 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
let syspkgs = self.syspkgs.clone();
|
let syspkgs = self.syspkgs.clone();
|
||||||
relm4::spawn(async move {
|
relm4::spawn(async move {
|
||||||
let result = match syspkgs {
|
let result = match syspkgs {
|
||||||
SystemPkgs::Legacy => runcmd(NscCmd::Rebuild, systemconfig, flakeargs, syspkgs).await,
|
SystemPkgs::Legacy => {
|
||||||
SystemPkgs::Flake => runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs).await,
|
runcmd(NscCmd::Rebuild, systemconfig, flakeargs, syspkgs, None).await
|
||||||
|
}
|
||||||
|
SystemPkgs::Flake => {
|
||||||
|
runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs, None).await
|
||||||
|
}
|
||||||
SystemPkgs::None => Ok(true),
|
SystemPkgs::None => Ok(true),
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
@ -161,7 +151,25 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
relm4::spawn(async move {
|
relm4::spawn(async move {
|
||||||
let result = match userpkgs {
|
let result = match userpkgs {
|
||||||
UserPkgs::Env => updateenv().await,
|
UserPkgs::Env => updateenv().await,
|
||||||
UserPkgs::Profile => updateprofile().await,
|
UserPkgs::Profile => updateprofile(None).await,
|
||||||
|
};
|
||||||
|
match result {
|
||||||
|
Ok(true) => {
|
||||||
|
sender.output(UpdatePageMsg::DoneWorking);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("UPDATE USER FAILED");
|
||||||
|
sender.output(UpdatePageMsg::FailedWorking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
UpdateAsyncHandlerMsg::UpdateUserPkgsRemove(pkgs) => {
|
||||||
|
let userpkgs = self.userpkgs.clone();
|
||||||
|
relm4::spawn(async move {
|
||||||
|
let result = match userpkgs {
|
||||||
|
UserPkgs::Env => updateenv().await,
|
||||||
|
UserPkgs::Profile => updateprofile(Some(pkgs)).await,
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
@ -180,12 +188,41 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
let syspkgs = self.syspkgs.clone();
|
let syspkgs = self.syspkgs.clone();
|
||||||
let userpkgs = self.userpkgs.clone();
|
let userpkgs = self.userpkgs.clone();
|
||||||
relm4::spawn(async move {
|
relm4::spawn(async move {
|
||||||
let result = runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs).await;
|
let result = runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs, None).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
match match userpkgs {
|
match match userpkgs {
|
||||||
UserPkgs::Env => updateenv().await,
|
UserPkgs::Env => updateenv().await,
|
||||||
UserPkgs::Profile => updateprofile().await,
|
UserPkgs::Profile => updateprofile(None).await,
|
||||||
|
} {
|
||||||
|
Ok(true) => {
|
||||||
|
sender.output(UpdatePageMsg::DoneWorking);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("UPDATE ALL FAILED");
|
||||||
|
sender.output(UpdatePageMsg::FailedWorking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("UPDATE ALL FAILED");
|
||||||
|
sender.output(UpdatePageMsg::FailedWorking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
UpdateAsyncHandlerMsg::UpdateAllRemove(userrmpkgs, sysrmpkgs) => {
|
||||||
|
let systemconfig = self.systemconfig.clone();
|
||||||
|
let flakeargs = self.flakeargs.clone();
|
||||||
|
let syspkgs = self.syspkgs.clone();
|
||||||
|
let userpkgs = self.userpkgs.clone();
|
||||||
|
relm4::spawn(async move {
|
||||||
|
let result = runcmd(NscCmd::All, systemconfig, flakeargs, syspkgs, Some(sysrmpkgs)).await;
|
||||||
|
match result {
|
||||||
|
Ok(true) => {
|
||||||
|
match match userpkgs {
|
||||||
|
UserPkgs::Env => updateenv().await,
|
||||||
|
UserPkgs::Profile => updateprofile(Some(userrmpkgs)).await,
|
||||||
} {
|
} {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
sender.output(UpdatePageMsg::DoneWorking);
|
sender.output(UpdatePageMsg::DoneWorking);
|
||||||
@ -209,10 +246,12 @@ impl Worker for UpdateAsyncHandler {
|
|||||||
|
|
||||||
async fn runcmd(
|
async fn runcmd(
|
||||||
cmd: NscCmd,
|
cmd: NscCmd,
|
||||||
_systemconfig: Option<String>,
|
systemconfig: String,
|
||||||
flakeargs: Option<String>,
|
flakeargs: Option<String>,
|
||||||
syspkgs: SystemPkgs,
|
syspkgs: SystemPkgs,
|
||||||
|
rmpkgs: Option<Vec<String>>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
|
let f = fs::read_to_string(&systemconfig)?;
|
||||||
let exe = match std::env::current_exe() {
|
let exe = match std::env::current_exe() {
|
||||||
Ok(mut e) => {
|
Ok(mut e) => {
|
||||||
e.pop(); // root/bin
|
e.pop(); // root/bin
|
||||||
@ -231,7 +270,12 @@ async fn runcmd(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let flakepathsplit = flakeargs.clone().unwrap_or_default().to_string();
|
let flakepathsplit = flakeargs.clone().unwrap_or_default().to_string();
|
||||||
let flakepath = flakepathsplit.split('#').collect::<Vec<&str>>().first().cloned().unwrap_or_default();
|
let flakepath = flakepathsplit
|
||||||
|
.split('#')
|
||||||
|
.collect::<Vec<&str>>()
|
||||||
|
.first()
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
let rebuildargs = if let Some(x) = flakeargs {
|
let rebuildargs = if let Some(x) = flakeargs {
|
||||||
let mut v = vec![String::from("--flake")];
|
let mut v = vec![String::from("--flake")];
|
||||||
@ -260,7 +304,36 @@ async fn runcmd(
|
|||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()?,
|
.spawn()?,
|
||||||
NscCmd::All => match syspkgs {
|
NscCmd::All => match syspkgs {
|
||||||
SystemPkgs::Legacy => tokio::process::Command::new("pkexec")
|
SystemPkgs::Legacy => {
|
||||||
|
if let Some(rmpkgs) = rmpkgs {
|
||||||
|
let newconfig =
|
||||||
|
match nix_editor::write::rmarr(&f, "environment.systemPackages", rmpkgs) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => {
|
||||||
|
return Err(anyhow!("Failed to write configuration.nix"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut cmd = tokio::process::Command::new("pkexec")
|
||||||
|
.arg(&exe)
|
||||||
|
.arg("channel")
|
||||||
|
.arg("--rebuild")
|
||||||
|
.arg("--update")
|
||||||
|
.arg("--output")
|
||||||
|
.arg(&systemconfig)
|
||||||
|
.arg("--")
|
||||||
|
.arg("switch")
|
||||||
|
.args(&rebuildargs)
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.spawn()?;
|
||||||
|
cmd.stdin
|
||||||
|
.take()
|
||||||
|
.unwrap()
|
||||||
|
.write_all(newconfig.as_bytes())
|
||||||
|
.await?;
|
||||||
|
cmd
|
||||||
|
} else {
|
||||||
|
tokio::process::Command::new("pkexec")
|
||||||
.arg(&exe)
|
.arg(&exe)
|
||||||
.arg("channel")
|
.arg("channel")
|
||||||
.arg("--rebuild")
|
.arg("--rebuild")
|
||||||
@ -268,19 +341,55 @@ async fn runcmd(
|
|||||||
.arg("switch")
|
.arg("switch")
|
||||||
.args(&rebuildargs)
|
.args(&rebuildargs)
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()?,
|
.spawn()?
|
||||||
SystemPkgs::Flake => tokio::process::Command::new("pkexec")
|
}
|
||||||
|
}
|
||||||
|
SystemPkgs::Flake => {
|
||||||
|
if let Some(rmpkgs) = rmpkgs {
|
||||||
|
let newconfig =
|
||||||
|
match nix_editor::write::rmarr(&f, "environment.systemPackages", rmpkgs) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => {
|
||||||
|
return Err(anyhow!("Failed to write configuration.nix"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut cmd = tokio::process::Command::new("pkexec")
|
||||||
.arg(&exe)
|
.arg(&exe)
|
||||||
.arg("flake")
|
.arg("flake")
|
||||||
.arg("--rebuild")
|
.arg("--rebuild")
|
||||||
.arg("--flakepath")
|
.arg("--flakepath")
|
||||||
.arg(flakepath)
|
.arg(&flakepath)
|
||||||
|
.arg("--update")
|
||||||
|
.arg("--output")
|
||||||
|
.arg(&systemconfig)
|
||||||
.arg("--")
|
.arg("--")
|
||||||
.arg("switch")
|
.arg("switch")
|
||||||
.arg("--impure")
|
.arg("--impure")
|
||||||
.args(&rebuildargs)
|
.args(&rebuildargs)
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()?,
|
.stdin(Stdio::piped())
|
||||||
|
.spawn()?;
|
||||||
|
cmd.stdin
|
||||||
|
.take()
|
||||||
|
.unwrap()
|
||||||
|
.write_all(newconfig.as_bytes())
|
||||||
|
.await?;
|
||||||
|
cmd
|
||||||
|
} else {
|
||||||
|
tokio::process::Command::new("pkexec")
|
||||||
|
.arg(&exe)
|
||||||
|
.arg("flake")
|
||||||
|
.arg("--rebuild")
|
||||||
|
.arg("--flakepath")
|
||||||
|
.arg(&flakepath)
|
||||||
|
.arg("--")
|
||||||
|
.arg("switch")
|
||||||
|
.arg("--impure")
|
||||||
|
.args(&rebuildargs)
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()?
|
||||||
|
}
|
||||||
|
}
|
||||||
SystemPkgs::None => return Ok(true),
|
SystemPkgs::None => return Ok(true),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -321,7 +430,38 @@ async fn updateenv() -> Result<bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn updateprofile() -> Result<bool> {
|
async fn updateprofile(rmpkgs: Option<Vec<String>>) -> Result<bool> {
|
||||||
|
if let Some(rmpkgs) = rmpkgs {
|
||||||
|
if !rmpkgs.is_empty() {
|
||||||
|
let mut cmd = tokio::process::Command::new("nix")
|
||||||
|
.arg("profile")
|
||||||
|
.arg("remove")
|
||||||
|
.args(
|
||||||
|
&rmpkgs
|
||||||
|
.iter()
|
||||||
|
.map(|x| format!(
|
||||||
|
"legacyPackages.x86_64-linux.{}",
|
||||||
|
x
|
||||||
|
))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
)
|
||||||
|
// Allow updating potential unfree packages
|
||||||
|
.arg("--impure")
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()?;
|
||||||
|
|
||||||
|
let stderr = cmd.stderr.take().unwrap();
|
||||||
|
let reader = tokio::io::BufReader::new(stderr);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
cmd.wait().await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut cmd = tokio::process::Command::new("nix")
|
let mut cmd = tokio::process::Command::new("nix")
|
||||||
.arg("profile")
|
.arg("profile")
|
||||||
.arg("upgrade")
|
.arg("upgrade")
|
||||||
|
134
src/ui/window.rs
134
src/ui/window.rs
@ -4,7 +4,7 @@ use crate::{
|
|||||||
config::{editconfig, getconfig},
|
config::{editconfig, getconfig},
|
||||||
packages::{AppData, LicenseEnum, PkgMaintainer, Platform},
|
packages::{AppData, LicenseEnum, PkgMaintainer, Platform},
|
||||||
},
|
},
|
||||||
ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg, rebuild::RebuildMsg},
|
ui::{installedpage::InstalledItem, pkgpage::PkgPageInit, welcome::WelcomeMsg, rebuild::RebuildMsg, updatepage::UNAVAILABLE_BROKER, unavailabledialog::UnavailableDialogMsg},
|
||||||
APPINFO,
|
APPINFO,
|
||||||
};
|
};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
@ -30,9 +30,9 @@ use super::{
|
|||||||
pkgtile::PkgTile,
|
pkgtile::PkgTile,
|
||||||
preferencespage::{PreferencesPageModel, PreferencesPageMsg},
|
preferencespage::{PreferencesPageModel, PreferencesPageMsg},
|
||||||
searchpage::{SearchItem, SearchPageModel, SearchPageMsg},
|
searchpage::{SearchItem, SearchPageModel, SearchPageMsg},
|
||||||
updatepage::{UpdateItem, UpdatePageInit, UpdatePageModel, UpdatePageMsg},
|
updatepage::{UpdateItem, UpdatePageInit, UpdatePageModel, UpdatePageMsg, UpdateType},
|
||||||
welcome::WelcomeModel,
|
welcome::WelcomeModel,
|
||||||
windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg}, rebuild::RebuildModel,
|
windowloading::{LoadErrorModel, LoadErrorMsg, WindowAsyncHandler, WindowAsyncHandlerMsg}, rebuild::RebuildModel, unavailabledialog::UnavailableItemModel,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static REBUILD_BROKER: MessageBroker<RebuildModel> = MessageBroker::new();
|
pub static REBUILD_BROKER: MessageBroker<RebuildModel> = MessageBroker::new();
|
||||||
@ -152,6 +152,7 @@ pub enum AppMsg {
|
|||||||
LoadCategory(PkgCategory),
|
LoadCategory(PkgCategory),
|
||||||
UpdateRecPkgs(Vec<String>),
|
UpdateRecPkgs(Vec<String>),
|
||||||
SetDarkMode(bool),
|
SetDarkMode(bool),
|
||||||
|
GetUnavailableItems(HashMap<String, String>, HashMap<String, String>, UpdateType),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@ -1825,6 +1826,133 @@ FROM pkgs JOIN meta ON (pkgs.attribute = meta.attribute) WHERE pkgs.attribute =
|
|||||||
let scheme = if dark { "Adwaita-dark" } else { "Adwaita" };
|
let scheme = if dark { "Adwaita-dark" } else { "Adwaita" };
|
||||||
self.rebuild.emit(RebuildMsg::SetScheme(scheme.to_string()));
|
self.rebuild.emit(RebuildMsg::SetScheme(scheme.to_string()));
|
||||||
}
|
}
|
||||||
|
AppMsg::GetUnavailableItems(userpkgs, syspkgs, updatetype) => {
|
||||||
|
info!("AppMsg::GetUnavailableItems");
|
||||||
|
let appdata: HashMap<String, AppData> = self
|
||||||
|
.appdata
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(k, v)| {
|
||||||
|
if syspkgs.contains_key(k) || userpkgs.contains_key(k) {
|
||||||
|
Some((k.to_string(), v.clone()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let poolref = self.pkgdb.clone();
|
||||||
|
relm4::spawn(async move {
|
||||||
|
let mut unavailableuser = vec![];
|
||||||
|
let mut unavailablesys = vec![];
|
||||||
|
if let Ok(pool) = &SqlitePool::connect(&format!("sqlite://{}", poolref)).await {
|
||||||
|
let mut sortuserpkgs = userpkgs.into_iter().collect::<Vec<_>>();
|
||||||
|
sortuserpkgs.sort();
|
||||||
|
for (pkg, msg) in sortuserpkgs {
|
||||||
|
if let Some(data) = appdata.get(&pkg) {
|
||||||
|
let pname: Result<(String,), sqlx::Error> =
|
||||||
|
sqlx::query_as("SELECT pname FROM pkgs WHERE attribute = $1")
|
||||||
|
.bind(&pkg)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await;
|
||||||
|
if let Ok(pname) = pname {
|
||||||
|
unavailableuser.push(UnavailableItemModel {
|
||||||
|
pkg: pkg.to_string(),
|
||||||
|
name: if let Some(name) = &data.name {
|
||||||
|
name.get("C").unwrap_or(&pname.0).to_string()
|
||||||
|
} else {
|
||||||
|
pname.0.to_string()
|
||||||
|
},
|
||||||
|
pname: pname.0.to_string(),
|
||||||
|
icon: data
|
||||||
|
.icon
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.cached.as_ref())
|
||||||
|
.map(|x| x[0].name.clone()),
|
||||||
|
message: msg
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
unavailableuser.push(UnavailableItemModel {
|
||||||
|
pkg: pkg.to_string(),
|
||||||
|
name: if let Some(name) = &data.name {
|
||||||
|
name.get("C").unwrap_or(&pkg).to_string()
|
||||||
|
} else {
|
||||||
|
pkg.to_string()
|
||||||
|
},
|
||||||
|
pname: String::new(),
|
||||||
|
icon: data
|
||||||
|
.icon
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.cached.as_ref())
|
||||||
|
.map(|x| x[0].name.clone()),
|
||||||
|
message: msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unavailableuser.push(UnavailableItemModel {
|
||||||
|
pkg: pkg.to_string(),
|
||||||
|
name: pkg.to_string(),
|
||||||
|
pname: String::new(),
|
||||||
|
icon: None,
|
||||||
|
message: msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut sortsyspkgs = syspkgs.into_iter().collect::<Vec<_>>();
|
||||||
|
sortsyspkgs.sort();
|
||||||
|
for (pkg, msg) in sortsyspkgs {
|
||||||
|
if let Some(data) = appdata.get(&pkg) {
|
||||||
|
let pname: Result<(String,), sqlx::Error> =
|
||||||
|
sqlx::query_as("SELECT pname FROM pkgs WHERE attribute = $1")
|
||||||
|
.bind(&pkg)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await;
|
||||||
|
if let Ok(pname) = pname {
|
||||||
|
unavailablesys.push(UnavailableItemModel {
|
||||||
|
pkg: pkg.to_string(),
|
||||||
|
name: if let Some(name) = &data.name {
|
||||||
|
name.get("C").unwrap_or(&pname.0).to_string()
|
||||||
|
} else {
|
||||||
|
pname.0.to_string()
|
||||||
|
},
|
||||||
|
pname: pname.0.to_string(),
|
||||||
|
icon: data
|
||||||
|
.icon
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.cached.as_ref())
|
||||||
|
.map(|x| x[0].name.clone()),
|
||||||
|
message: msg
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
unavailablesys.push(UnavailableItemModel {
|
||||||
|
pkg: pkg.to_string(),
|
||||||
|
name: if let Some(name) = &data.name {
|
||||||
|
name.get("C").unwrap_or(&pkg).to_string()
|
||||||
|
} else {
|
||||||
|
pkg.to_string()
|
||||||
|
},
|
||||||
|
pname: String::new(),
|
||||||
|
icon: data
|
||||||
|
.icon
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.cached.as_ref())
|
||||||
|
.map(|x| x[0].name.clone()),
|
||||||
|
message: msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unavailablesys.push(UnavailableItemModel {
|
||||||
|
pkg: pkg.to_string(),
|
||||||
|
name: pkg.to_string(),
|
||||||
|
pname: String::new(),
|
||||||
|
icon: None,
|
||||||
|
message: msg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
UNAVAILABLE_BROKER.send(UnavailableDialogMsg::Show(unavailableuser, unavailablesys, updatetype));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user