mirror of
https://github.com/snowfallorg/nix-software-center.git
synced 2024-09-11 13:25:38 +03:00
Refactor around nix-data crate
This commit is contained in:
parent
5532c19944
commit
ee0c62b3da
1192
Cargo.lock
generated
1192
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
18
Cargo.toml
18
Cargo.toml
@ -1,12 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nix-software-center"
|
name = "nix-software-center"
|
||||||
version = "0.0.3"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
default-run = "nix-software-center"
|
default-run = "nix-software-center"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
relm4 = { git = "https://github.com/Relm4/Relm4", tag = "v0.5.0-beta.2", features = ["all"] }
|
relm4 = { git = "https://github.com/Relm4/Relm4", tag = "v0.5.0-beta.3", features = ["all"] }
|
||||||
relm4-components = { package = "relm4-components", git = "https://github.com/Relm4/Relm4", tag = "v0.5.0-beta.2"}
|
relm4-components = { package = "relm4-components", git = "https://github.com/Relm4/Relm4", tag = "v0.5.0-beta.3"}
|
||||||
adw = { package = "libadwaita", git = "https://gitlab.gnome.org/World/Rust/libadwaita-rs", features = ["v1_2", "gtk_v4_6"] }
|
adw = { package = "libadwaita", git = "https://gitlab.gnome.org/World/Rust/libadwaita-rs", features = ["v1_2", "gtk_v4_6"] }
|
||||||
gtk = { package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs", features = ["v4_6"] }
|
gtk = { package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs", features = ["v4_6"] }
|
||||||
tokio = { version = "1.21", features = ["rt", "macros", "time", "rt-multi-thread", "sync", "process"] }
|
tokio = { version = "1.21", features = ["rt", "macros", "time", "rt-multi-thread", "sync", "process"] }
|
||||||
@ -15,12 +15,13 @@ tracker = "0.1"
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9"
|
||||||
simd-json = { version = "0.6", features = ["allow-non-simd"] }
|
|
||||||
|
|
||||||
nix-editor = "0.2.12"
|
nix-editor = "0.3.0-beta.1"
|
||||||
|
nix-data = { git = "https://github.com/snowflakelinux/nix-data", rev = "a5168c768e8cf8bd3e1afe1772f8e05e5b03ed95" }
|
||||||
|
|
||||||
|
sqlx = { version = "0.6", features = [ "runtime-tokio-native-tls" , "sqlite" ] }
|
||||||
|
|
||||||
html2pango = "0.5"
|
html2pango = "0.5"
|
||||||
brotli = "3.3"
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
@ -30,11 +31,10 @@ reqwest = { version = "0.11", features = ["blocking"] }
|
|||||||
sha256 = "1.0"
|
sha256 = "1.0"
|
||||||
image = "0.24"
|
image = "0.24"
|
||||||
spdx = "0.9"
|
spdx = "0.9"
|
||||||
edit-distance = "2.1"
|
|
||||||
ijson = "0.1"
|
|
||||||
strum = "0.24"
|
strum = "0.24"
|
||||||
strum_macros = "0.24"
|
strum_macros = "0.24"
|
||||||
which = "4.3"
|
|
||||||
|
anyhow = "1.0"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [".", "nsc-helper"]
|
members = [".", "nsc-helper"]
|
||||||
|
17
default.nix
17
default.nix
@ -2,16 +2,6 @@
|
|||||||
, lib ? import <nixpkgs/lib>
|
, lib ? import <nixpkgs/lib>
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
libadwaita-git = pkgs.libadwaita.overrideAttrs (oldAttrs: rec {
|
|
||||||
version = "1.2.0";
|
|
||||||
src = pkgs.fetchFromGitLab {
|
|
||||||
domain = "gitlab.gnome.org";
|
|
||||||
owner = "GNOME";
|
|
||||||
repo = "libadwaita";
|
|
||||||
rev = version;
|
|
||||||
hash = "sha256-3lH7Vi9M8k+GSrCpvruRpLrIpMoOakKbcJlaAc/FK+U=";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
nixos-appstream-data = (import
|
nixos-appstream-data = (import
|
||||||
(pkgs.fetchFromGitHub {
|
(pkgs.fetchFromGitHub {
|
||||||
owner = "vlinkz";
|
owner = "vlinkz";
|
||||||
@ -23,14 +13,14 @@ let
|
|||||||
in
|
in
|
||||||
pkgs.stdenv.mkDerivation rec {
|
pkgs.stdenv.mkDerivation rec {
|
||||||
pname = "nix-software-center";
|
pname = "nix-software-center";
|
||||||
version = "0.0.3";
|
version = "0.1.0";
|
||||||
|
|
||||||
src = [ ./. ];
|
src = [ ./. ];
|
||||||
|
|
||||||
cargoDeps = pkgs.rustPlatform.fetchCargoTarball {
|
cargoDeps = pkgs.rustPlatform.fetchCargoTarball {
|
||||||
inherit src;
|
inherit src;
|
||||||
name = "${pname}-${version}";
|
name = "${pname}-${version}";
|
||||||
hash = "sha256-8eUFl3N1tVZ2j+S6iIIpFSH5F5fXAl5+Yz3xS/NxF2I=";
|
hash = "sha256-NqjBlNHt9rlej5Y3R6cYDZFwpDIFa3ZmfsxSXaTUOUI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
@ -54,7 +44,8 @@ pkgs.stdenv.mkDerivation rec {
|
|||||||
glib
|
glib
|
||||||
gtk4
|
gtk4
|
||||||
gtksourceview5
|
gtksourceview5
|
||||||
libadwaita-git
|
libadwaita
|
||||||
|
libxml2
|
||||||
openssl
|
openssl
|
||||||
wayland
|
wayland
|
||||||
gnome.adwaita-icon-theme
|
gnome.adwaita-icon-theme
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1664195620,
|
"lastModified": 1665732960,
|
||||||
"narHash": "sha256-/0V1a1gAR+QbiQe4aCxBoivhkxss0xyt2mBD6yDrgjw=",
|
"narHash": "sha256-WBZ+uSHKFyjvd0w4inbm0cNExYTn8lpYFcHEes8tmec=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "62228ccc672ed000f35b1e5c82e4183e46767e52",
|
"rev": "4428e23312933a196724da2df7ab78eb5e67a88e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
12
flake.nix
12
flake.nix
@ -10,16 +10,6 @@
|
|||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
};
|
};
|
||||||
libadwaita-git = pkgs.libadwaita.overrideAttrs (oldAttrs: rec {
|
|
||||||
version = "1.2.0";
|
|
||||||
src = pkgs.fetchFromGitLab {
|
|
||||||
domain = "gitlab.gnome.org";
|
|
||||||
owner = "GNOME";
|
|
||||||
repo = "libadwaita";
|
|
||||||
rev = version;
|
|
||||||
hash = "sha256-3lH7Vi9M8k+GSrCpvruRpLrIpMoOakKbcJlaAc/FK+U=";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
nixos-appstream-data = pkgs.fetchFromGitHub {
|
nixos-appstream-data = pkgs.fetchFromGitHub {
|
||||||
owner = "vlinkz";
|
owner = "vlinkz";
|
||||||
repo = "nixos-appstream-data";
|
repo = "nixos-appstream-data";
|
||||||
@ -58,7 +48,7 @@
|
|||||||
graphene
|
graphene
|
||||||
gtk4
|
gtk4
|
||||||
gtksourceview5
|
gtksourceview5
|
||||||
libadwaita-git
|
libadwaita
|
||||||
meson
|
meson
|
||||||
ninja
|
ninja
|
||||||
openssl
|
openssl
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
project(
|
project(
|
||||||
'nix-software-center',
|
'nix-software-center',
|
||||||
'rust',
|
'rust',
|
||||||
version: '0.0.3',
|
version: '0.1.0',
|
||||||
meson_version: '>= 0.59',
|
meson_version: '>= 0.59',
|
||||||
license: 'GPL-3.0-only',
|
license: 'GPL-3.0-only',
|
||||||
)
|
)
|
||||||
|
@ -8,6 +8,5 @@ fn main() {
|
|||||||
gio::resources_register(&res);
|
gio::resources_register(&res);
|
||||||
}
|
}
|
||||||
let app = RelmApp::new(nix_software_center::config::APP_ID);
|
let app = RelmApp::new(nix_software_center::config::APP_ID);
|
||||||
let application = app.app.clone();
|
app.run::<AppModel>(());
|
||||||
app.run::<AppModel>(application);
|
|
||||||
}
|
}
|
||||||
|
@ -1,56 +1,15 @@
|
|||||||
use std::{
|
use anyhow::Result;
|
||||||
env,
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
error::Error,
|
|
||||||
fs::{self, File},
|
|
||||||
io::Write,
|
|
||||||
path::Path,
|
|
||||||
};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
pub fn getconfig() -> Option<NixDataConfig> {
|
||||||
|
if let Ok(c) = nix_data::config::configfile::getconfig() {
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
|
|
||||||
pub struct NscConfig {
|
|
||||||
pub systemconfig: Option<String>,
|
|
||||||
pub flake: Option<String>,
|
|
||||||
pub flakearg: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getconfig() -> Option<NscConfig> {
|
|
||||||
if let Ok(c) = getconfigval() {
|
|
||||||
Some(c)
|
Some(c)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getconfigval() -> Result<NscConfig, Box<dyn Error>> {
|
pub fn editconfig(config: NixDataConfig) -> Result<()> {
|
||||||
let configfile = checkconfig()?;
|
nix_data::config::configfile::setuserconfig(config)?;
|
||||||
let config: NscConfig =
|
|
||||||
serde_json::from_reader(File::open(format!("{}/config.json", configfile))?)?;
|
|
||||||
Ok(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn checkconfig() -> Result<String, Box<dyn Error>> {
|
|
||||||
let cfgdir = format!("{}/.config/nix-software-center", env::var("HOME")?);
|
|
||||||
if !Path::is_file(Path::new(&format!("{}/config.json", &cfgdir))) {
|
|
||||||
if !Path::is_file(Path::new("/etc/nix-software-center/config.json")) {
|
|
||||||
Err(Box::new(std::io::Error::new(
|
|
||||||
std::io::ErrorKind::InvalidData,
|
|
||||||
"No config file found",
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
Ok("/etc/nix-software-center/".to_string())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(cfgdir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn editconfig(config: NscConfig) -> Result<(), Box<dyn Error>> {
|
|
||||||
let cfgdir = format!("{}/.config/nix-software-center", env::var("HOME")?);
|
|
||||||
fs::create_dir_all(&cfgdir)?;
|
|
||||||
let json = serde_json::to_string_pretty(&config)?;
|
|
||||||
let mut file = File::create(format!("{}/config.json", cfgdir))?;
|
|
||||||
file.write_all(json.as_bytes())?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
pub mod cache;
|
// pub mod cache;
|
||||||
pub mod packages;
|
pub mod packages;
|
||||||
pub mod config;
|
pub mod config;
|
@ -1,91 +1,58 @@
|
|||||||
use flate2::bufread::GzDecoder;
|
use flate2::bufread::GzDecoder;
|
||||||
use ijson::IString;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs;
|
use std::{self, fs::File, collections::HashMap, io::{BufReader, Read}};
|
||||||
use std::io::Read;
|
|
||||||
use std::{self, fs::File, collections::HashMap, error::Error, env, io::BufReader};
|
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::APPINFO;
|
use crate::APPINFO;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct PackageBase {
|
|
||||||
packages: HashMap<String, Package>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
|
||||||
pub struct Package {
|
|
||||||
pub system: IString,
|
|
||||||
pub pname: IString,
|
|
||||||
pub meta: Meta,
|
|
||||||
pub version: IString,
|
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
pub appdata: Option<AppData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
|
||||||
pub struct Meta {
|
|
||||||
pub broken: Option<bool>,
|
|
||||||
pub insecure: Option<bool>,
|
|
||||||
pub unsupported: Option<bool>,
|
|
||||||
pub unfree: Option<bool>,
|
|
||||||
pub description: Option<IString>,
|
|
||||||
#[serde(rename = "longDescription")]
|
|
||||||
pub longdescription: Option<IString>,
|
|
||||||
pub homepage: Option<StrOrVec>,
|
|
||||||
pub maintainers: Option<ijson::IValue>,
|
|
||||||
pub position: Option<IString>,
|
|
||||||
pub license: Option<LicenseEnum>,
|
|
||||||
pub platforms: Option<Platform>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum StrOrVec {
|
pub enum StrOrVec {
|
||||||
Single(IString),
|
Single(String),
|
||||||
List(Vec<IString>),
|
List(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Platform {
|
pub enum Platform {
|
||||||
Single(IString),
|
Single(String),
|
||||||
List(Vec<IString>),
|
List(Vec<String>),
|
||||||
ListList(Vec<Vec<IString>>),
|
ListList(Vec<Vec<String>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum LicenseEnum {
|
pub enum LicenseEnum {
|
||||||
Single(License),
|
Single(License),
|
||||||
List(Vec<License>),
|
List(Vec<License>),
|
||||||
SingleStr(IString),
|
SingleStr(String),
|
||||||
VecStr(Vec<IString>),
|
VecStr(Vec<String>),
|
||||||
Mixed(Vec<LicenseEnum>)
|
Mixed(Vec<LicenseEnum>)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct License {
|
pub struct License {
|
||||||
pub free: Option<bool>,
|
pub free: Option<bool>,
|
||||||
#[serde(rename = "fullName")]
|
#[serde(rename = "fullName")]
|
||||||
pub fullname: Option<IString>,
|
pub fullname: Option<String>,
|
||||||
#[serde(rename = "spdxId")]
|
#[serde(rename = "spdxId")]
|
||||||
pub spdxid: Option<IString>,
|
pub spdxid: Option<String>,
|
||||||
pub url: Option<IString>,
|
pub url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct PkgMaintainer {
|
pub struct PkgMaintainer {
|
||||||
pub email: Option<IString>,
|
pub email: Option<String>,
|
||||||
pub github: Option<IString>,
|
pub github: Option<String>,
|
||||||
pub matrix: Option<IString>,
|
pub matrix: Option<String>,
|
||||||
pub name: Option<IString>
|
pub name: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
||||||
pub struct AppData {
|
pub struct AppData {
|
||||||
#[serde(rename = "Type")]
|
#[serde(rename = "Type")]
|
||||||
pub metatype: IString,
|
pub metatype: String,
|
||||||
#[serde(rename = "ID")]
|
#[serde(rename = "ID")]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
#[serde(rename = "Package")]
|
#[serde(rename = "Package")]
|
||||||
@ -110,7 +77,7 @@ pub struct AppData {
|
|||||||
pub categories: Option<Vec<String>>,
|
pub categories: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AppUrl {
|
pub struct AppUrl {
|
||||||
pub homepage: Option<String>,
|
pub homepage: Option<String>,
|
||||||
pub bugtracker: Option<String>,
|
pub bugtracker: Option<String>,
|
||||||
@ -118,27 +85,27 @@ pub struct AppUrl {
|
|||||||
pub donation: Option<String>,
|
pub donation: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AppIconList {
|
pub struct AppIconList {
|
||||||
pub cached: Option<Vec<AppIcon>>,
|
pub cached: Option<Vec<AppIcon>>,
|
||||||
pub stock: Option<String>,
|
pub stock: Option<String>,
|
||||||
// TODO: add support for other icon types
|
// TODO: add support for other icon types
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
||||||
pub struct AppIcon {
|
pub struct AppIcon {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AppLaunchable {
|
pub struct AppLaunchable {
|
||||||
#[serde(rename = "desktop-id")]
|
#[serde(rename = "desktop-id")]
|
||||||
pub desktopid: Vec<String>
|
pub desktopid: Vec<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AppProvides {
|
pub struct AppProvides {
|
||||||
pub binaries: Option<Vec<String>>,
|
pub binaries: Option<Vec<String>>,
|
||||||
pub ids: Option<Vec<String>>,
|
pub ids: Option<Vec<String>>,
|
||||||
@ -146,7 +113,7 @@ pub struct AppProvides {
|
|||||||
pub libraries: Option<Vec<String>>,
|
pub libraries: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AppScreenshot {
|
pub struct AppScreenshot {
|
||||||
pub default: Option<bool>,
|
pub default: Option<bool>,
|
||||||
pub thumbnails: Option<Vec<String>>,
|
pub thumbnails: Option<Vec<String>>,
|
||||||
@ -154,33 +121,12 @@ pub struct AppScreenshot {
|
|||||||
pub sourceimage: Option<AppScreenshotImage>,
|
pub sourceimage: Option<AppScreenshotImage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct AppScreenshotImage {
|
pub struct AppScreenshotImage {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
pub fn appsteamdata() -> Result<HashMap<String, AppData>> {
|
||||||
struct FlakePkgs {
|
|
||||||
packages: HashMap<String, FlakeJson>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
struct FlakeJson {
|
|
||||||
pname: IString,
|
|
||||||
version: IString,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn readpkgs() -> Result<HashMap<String, Package>, Box<dyn Error + Send + Sync>> {
|
|
||||||
info!("Reading package list");
|
|
||||||
let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
|
|
||||||
let cachefile = format!("{}/packages.json", cachedir);
|
|
||||||
let file = File::open(cachefile)?;
|
|
||||||
let reader = BufReader::new(file);
|
|
||||||
trace!("Reading packages.json");
|
|
||||||
let pkgbase: PackageBase = simd_json::serde::from_reader(reader)?;
|
|
||||||
trace!("Finished reading packages.json");
|
|
||||||
let mut pkgs = pkgbase.packages;
|
|
||||||
debug!("APPDATADIR {}", APPINFO);
|
|
||||||
let appdata = File::open(&format!("{}/xmls/nixos_x86_64_linux.yml.gz", APPINFO))?;
|
let appdata = File::open(&format!("{}/xmls/nixos_x86_64_linux.yml.gz", APPINFO))?;
|
||||||
let appreader = BufReader::new(appdata);
|
let appreader = BufReader::new(appdata);
|
||||||
let mut d = GzDecoder::new(appreader);
|
let mut d = GzDecoder::new(appreader);
|
||||||
@ -188,61 +134,15 @@ pub async fn readpkgs() -> Result<HashMap<String, Package>, Box<dyn Error + Sen
|
|||||||
d.read_to_string(&mut s)?;
|
d.read_to_string(&mut s)?;
|
||||||
let mut files = s.split("\n---\n").collect::<Vec<_>>();
|
let mut files = s.split("\n---\n").collect::<Vec<_>>();
|
||||||
files.remove(0);
|
files.remove(0);
|
||||||
|
|
||||||
|
let mut out = HashMap::new();
|
||||||
|
|
||||||
for f in files {
|
for f in files {
|
||||||
if let Ok(appstream) = serde_yaml::from_str::<AppData>(f) {
|
if let Ok(appstream) = serde_yaml::from_str::<AppData>(f) {
|
||||||
if let Some(p) = pkgs.get_mut(&appstream.package.to_string()) {
|
out.insert(appstream.package.to_string(), appstream);
|
||||||
p.appdata = Some(appstream);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
warn!("Failed to parse some appstream data");
|
warn!("Failed to parse some appstream data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(pkgs)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readlegacysyspkgs() -> Result<HashMap<String, String>, Box<dyn Error + Send + Sync>> {
|
|
||||||
info!("Reading legacy system package list");
|
|
||||||
let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
|
|
||||||
let cachefile = format!("{}/syspackages.json", cachedir);
|
|
||||||
if let Ok(f) = fs::read_to_string(&cachefile) {
|
|
||||||
if f.trim().is_empty() {
|
|
||||||
return Ok(HashMap::new());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let file = File::open(cachefile)?;
|
|
||||||
let reader = BufReader::new(file);
|
|
||||||
let newpkgs: HashMap<String, String> = simd_json::serde::from_reader(reader)?;
|
|
||||||
Ok(newpkgs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn readflakesyspkgs() -> Result<HashMap<String, String>, Box<dyn Error + Send + Sync>> {
|
|
||||||
info!("Reading flake system package list");
|
|
||||||
let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
|
|
||||||
let cachefile = format!("{}/syspackages.json", cachedir);
|
|
||||||
if let Ok(f) = fs::read_to_string(&cachefile) {
|
|
||||||
if f.trim().is_empty() {
|
|
||||||
return Ok(HashMap::new());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let file = File::open(cachefile)?;
|
|
||||||
let reader = BufReader::new(file);
|
|
||||||
let newpkgs: HashMap<String, FlakeJson> = simd_json::serde::from_reader(reader)?;
|
|
||||||
let newpkgs = newpkgs.into_iter().filter_map(|(k, v)| if let Some(pkg) = k.strip_prefix("legacyPackages.x86_64-linux.") { Some((pkg.to_string(), v.version.to_string())) } else { None }).collect::<HashMap<_, _>>();
|
|
||||||
Ok(newpkgs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn readprofilepkgs() -> Result<HashMap<String, String>, Box<dyn Error + Send + Sync>> {
|
|
||||||
info!("Reading profile package list");
|
|
||||||
let cachedir = format!("{}/.cache/nix-software-center/", env::var("HOME")?);
|
|
||||||
let cachefile = format!("{}/profilepackages.json", cachedir);
|
|
||||||
if let Ok(f) = fs::read_to_string(&cachefile) {
|
|
||||||
if f.trim().is_empty() {
|
|
||||||
return Ok(HashMap::new());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let file = File::open(cachefile)?;
|
|
||||||
let reader = BufReader::new(file);
|
|
||||||
let profilepkgs: FlakePkgs = simd_json::serde::from_reader(reader)?;
|
|
||||||
let profilepkgs = profilepkgs.packages.into_iter().map(|(pkg, v)| (pkg.to_string(), v.version.to_string())).collect::<HashMap<_, _>>();
|
|
||||||
Ok(profilepkgs)
|
|
||||||
}
|
|
@ -17,7 +17,7 @@ pub enum AboutPageMsg {
|
|||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for AboutPageModel {
|
impl SimpleComponent for AboutPageModel {
|
||||||
type InitParams = gtk::Window;
|
type Init = gtk::Window;
|
||||||
type Input = AboutPageMsg;
|
type Input = AboutPageMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = AboutPageWidgets;
|
type Widgets = AboutPageWidgets;
|
||||||
@ -40,7 +40,7 @@ impl SimpleComponent for AboutPageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
parent_window: Self::InitParams,
|
parent_window: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
_sender: ComponentSender<Self>,
|
_sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
|
@ -5,7 +5,7 @@ use strum_macros::{EnumIter, Display};
|
|||||||
|
|
||||||
use super::window::AppMsg;
|
use super::window::AppMsg;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub struct PkgGroup {
|
pub struct PkgGroup {
|
||||||
pub category: PkgCategory,
|
pub category: PkgCategory,
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ impl FactoryComponent for PkgGroup {
|
|||||||
type Output = PkgCategoryMsg;
|
type Output = PkgCategoryMsg;
|
||||||
type Widgets = PkgGroupWidgets;
|
type Widgets = PkgGroupWidgets;
|
||||||
type ParentWidget = gtk::FlowBox;
|
type ParentWidget = gtk::FlowBox;
|
||||||
type ParentMsg = AppMsg;
|
type ParentInput = AppMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
gtk::FlowBoxChild {
|
gtk::FlowBoxChild {
|
||||||
@ -95,7 +95,7 @@ impl FactoryComponent for PkgGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_to_parent_msg(output: Self::Output) -> Option<AppMsg> {
|
fn output_to_parent_input(output: Self::Output) -> Option<AppMsg> {
|
||||||
Some(match output {
|
Some(match output {
|
||||||
PkgCategoryMsg::Open(x) => AppMsg::OpenCategoryPage(x),
|
PkgCategoryMsg::Open(x) => AppMsg::OpenCategoryPage(x),
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use super::{window::*, categories::PkgCategory, categorytile::CategoryTile};
|
use super::{window::*, categories::PkgCategory, categorytile::CategoryTile};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use relm4::{factory::*, *};
|
use relm4::{factory::*, *};
|
||||||
|
use log::*;
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -22,12 +23,19 @@ pub enum CategoryPageMsg {
|
|||||||
UpdateInstalled(Vec<String>, Vec<String>)
|
UpdateInstalled(Vec<String>, Vec<String>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CategoryPageAsyncMsg {
|
||||||
|
PushRec(CategoryTile),
|
||||||
|
Push(CategoryTile),
|
||||||
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for CategoryPageModel {
|
impl Component for CategoryPageModel {
|
||||||
type InitParams = ();
|
type Init = ();
|
||||||
type Input = CategoryPageMsg;
|
type Input = CategoryPageMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = CategoryPageWidgets;
|
type Widgets = CategoryPageWidgets;
|
||||||
|
type CommandOutput = CategoryPageAsyncMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
@ -59,11 +67,14 @@ impl SimpleComponent for CategoryPageModel {
|
|||||||
set_maximum_size: 1000,
|
set_maximum_size: 1000,
|
||||||
set_tightening_threshold: 750,
|
set_tightening_threshold: 750,
|
||||||
if model.busy {
|
if model.busy {
|
||||||
|
#[name(spinner)]
|
||||||
gtk::Spinner {
|
gtk::Spinner {
|
||||||
|
set_hexpand: true,
|
||||||
|
set_vexpand: true,
|
||||||
set_halign: gtk::Align::Center,
|
set_halign: gtk::Align::Center,
|
||||||
set_valign: gtk::Align::Center,
|
set_valign: gtk::Align::Center,
|
||||||
set_spinning: true,
|
set_spinning: true,
|
||||||
set_height_request: 32,
|
set_size_request: (64, 64),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
@ -115,14 +126,14 @@ impl SimpleComponent for CategoryPageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
(): Self::InitParams,
|
(): Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let model = CategoryPageModel {
|
let model = CategoryPageModel {
|
||||||
category: PkgCategory::Audio,
|
category: PkgCategory::Audio,
|
||||||
recommendedapps: FactoryVecDeque::new(gtk::FlowBox::new(), &sender.input),
|
recommendedapps: FactoryVecDeque::new(gtk::FlowBox::new(), sender.input_sender()),
|
||||||
apps: FactoryVecDeque::new(gtk::FlowBox::new(), &sender.input),
|
apps: FactoryVecDeque::new(gtk::FlowBox::new(), sender.input_sender()),
|
||||||
busy: true,
|
busy: true,
|
||||||
tracker: 0
|
tracker: 0
|
||||||
};
|
};
|
||||||
@ -139,30 +150,39 @@ impl SimpleComponent for CategoryPageModel {
|
|||||||
self.reset();
|
self.reset();
|
||||||
match msg {
|
match msg {
|
||||||
CategoryPageMsg::Close => {
|
CategoryPageMsg::Close => {
|
||||||
let mut recapps_guard = self.recommendedapps.guard();
|
// let mut recapps_guard = self.recommendedapps.guard();
|
||||||
let mut apps_guard = self.apps.guard();
|
// let mut apps_guard = self.apps.guard();
|
||||||
recapps_guard.clear();
|
// recapps_guard.clear();
|
||||||
apps_guard.clear();
|
// apps_guard.clear();
|
||||||
sender.output(AppMsg::FrontFrontPage)
|
sender.output(AppMsg::FrontFrontPage)
|
||||||
}
|
}
|
||||||
CategoryPageMsg::OpenPkg(pkg) => {
|
CategoryPageMsg::OpenPkg(pkg) => {
|
||||||
sender.output(AppMsg::OpenPkg(pkg))
|
sender.output(AppMsg::OpenPkg(pkg))
|
||||||
}
|
}
|
||||||
CategoryPageMsg::Open(category, catrec, catall) => {
|
CategoryPageMsg::Open(category, catrec, catall) => {
|
||||||
|
info!("CategoryPageMsg::Open");
|
||||||
self.set_category(category);
|
self.set_category(category);
|
||||||
let mut recapps_guard = self.recommendedapps.guard();
|
let mut recapps_guard = self.recommendedapps.guard();
|
||||||
recapps_guard.clear();
|
recapps_guard.clear();
|
||||||
|
recapps_guard.drop();
|
||||||
for app in catrec {
|
for app in catrec {
|
||||||
recapps_guard.push_back(app);
|
sender.oneshot_command(async move {
|
||||||
|
CategoryPageAsyncMsg::PushRec(app)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
let mut apps_guard = self.apps.guard();
|
let mut apps_guard = self.apps.guard();
|
||||||
apps_guard.clear();
|
apps_guard.clear();
|
||||||
|
apps_guard.drop();
|
||||||
for app in catall {
|
for app in catall {
|
||||||
apps_guard.push_back(app);
|
sender.oneshot_command(async move {
|
||||||
|
CategoryPageAsyncMsg::Push(app)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
self.busy = false;
|
self.busy = false;
|
||||||
|
info!("DONE CategoryPageMsg::Open");
|
||||||
}
|
}
|
||||||
CategoryPageMsg::Loading(category) => {
|
CategoryPageMsg::Loading(category) => {
|
||||||
|
info!("CategoryPageMsg::Loading");
|
||||||
self.set_category(category);
|
self.set_category(category);
|
||||||
self.busy = true;
|
self.busy = true;
|
||||||
}
|
}
|
||||||
@ -199,4 +219,19 @@ impl SimpleComponent for CategoryPageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_cmd(&mut self, msg: Self::CommandOutput, _sender: ComponentSender<Self>) {
|
||||||
|
match msg {
|
||||||
|
CategoryPageAsyncMsg::PushRec(tile) => {
|
||||||
|
let mut recapps_guard = self.recommendedapps.guard();
|
||||||
|
recapps_guard.push_back(tile);
|
||||||
|
recapps_guard.drop();
|
||||||
|
}
|
||||||
|
CategoryPageAsyncMsg::Push(tile) => {
|
||||||
|
let mut apps_guard = self.apps.guard();
|
||||||
|
apps_guard.push_back(tile);
|
||||||
|
apps_guard.drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ use relm4::adw::prelude::*;
|
|||||||
use relm4::gtk::pango;
|
use relm4::gtk::pango;
|
||||||
use relm4::{factory::*, *};
|
use relm4::{factory::*, *};
|
||||||
|
|
||||||
#[derive(Default, Debug, PartialEq, Clone)]
|
#[derive(Default, Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct CategoryTile {
|
pub struct CategoryTile {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub pkg: String,
|
pub pkg: String,
|
||||||
@ -31,7 +31,7 @@ impl FactoryComponent for CategoryTile {
|
|||||||
type Output = CategoryTileMsg;
|
type Output = CategoryTileMsg;
|
||||||
type Widgets = CategoryTileWidgets;
|
type Widgets = CategoryTileWidgets;
|
||||||
type ParentWidget = gtk::FlowBox;
|
type ParentWidget = gtk::FlowBox;
|
||||||
type ParentMsg = CategoryPageMsg;
|
type ParentInput = CategoryPageMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
gtk::FlowBoxChild {
|
gtk::FlowBoxChild {
|
||||||
@ -176,7 +176,7 @@ impl FactoryComponent for CategoryTile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_to_parent_msg(output: Self::Output) -> Option<CategoryPageMsg> {
|
fn output_to_parent_input(output: Self::Output) -> Option<CategoryPageMsg> {
|
||||||
Some(match output {
|
Some(match output {
|
||||||
CategoryTileMsg::Open(x) => CategoryPageMsg::OpenPkg(x),
|
CategoryTileMsg::Open(x) => CategoryPageMsg::OpenPkg(x),
|
||||||
})
|
})
|
||||||
|
@ -28,7 +28,7 @@ pub enum InstalledPageMsg {
|
|||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for InstalledPageModel {
|
impl SimpleComponent for InstalledPageModel {
|
||||||
type InitParams = (SystemPkgs, UserPkgs);
|
type Init = (SystemPkgs, UserPkgs);
|
||||||
type Input = InstalledPageMsg;
|
type Input = InstalledPageMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = InstalledPageWidgets;
|
type Widgets = InstalledPageWidgets;
|
||||||
@ -93,13 +93,13 @@ impl SimpleComponent for InstalledPageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
(systempkgtype, userpkgtype): Self::InitParams,
|
(systempkgtype, userpkgtype): Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let model = InstalledPageModel {
|
let model = InstalledPageModel {
|
||||||
installeduserlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
|
installeduserlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
installedsystemlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
|
installedsystemlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
updatetracker: 0,
|
updatetracker: 0,
|
||||||
userpkgtype,
|
userpkgtype,
|
||||||
systempkgtype,
|
systempkgtype,
|
||||||
@ -196,7 +196,7 @@ impl SimpleComponent for InstalledPageModel {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct InstalledItem {
|
pub struct InstalledItem {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub pkg: Option<String>,
|
pub pkg: Option<String>,
|
||||||
@ -207,7 +207,7 @@ pub struct InstalledItem {
|
|||||||
pub busy: bool,
|
pub busy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct InstalledItemModel {
|
pub struct InstalledItemModel {
|
||||||
pub item: InstalledItem,
|
pub item: InstalledItem,
|
||||||
}
|
}
|
||||||
@ -230,7 +230,7 @@ impl FactoryComponent for InstalledItemModel {
|
|||||||
type Output = InstalledItemMsg;
|
type Output = InstalledItemMsg;
|
||||||
type Widgets = InstalledItemWidgets;
|
type Widgets = InstalledItemWidgets;
|
||||||
type ParentWidget = adw::gtk::ListBox;
|
type ParentWidget = adw::gtk::ListBox;
|
||||||
type ParentMsg = InstalledPageMsg;
|
type ParentInput = InstalledPageMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
adw::PreferencesRow {
|
adw::PreferencesRow {
|
||||||
@ -363,7 +363,7 @@ impl FactoryComponent for InstalledItemModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_to_parent_msg(output: Self::Output) -> Option<InstalledPageMsg> {
|
fn output_to_parent_input(output: Self::Output) -> Option<InstalledPageMsg> {
|
||||||
Some(match output {
|
Some(match output {
|
||||||
InstalledItemMsg::Delete(item) => InstalledPageMsg::Remove(item),
|
InstalledItemMsg::Delete(item) => InstalledPageMsg::Remove(item),
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use crate::parse::config::NscConfig;
|
|
||||||
|
|
||||||
use super::pkgpage::{InstallType, PkgAction, PkgMsg, WorkPkg};
|
use super::pkgpage::{InstallType, PkgAction, PkgMsg, WorkPkg};
|
||||||
use super::window::{SystemPkgs, UserPkgs};
|
use super::window::{SystemPkgs, UserPkgs};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -25,7 +24,7 @@ pub struct InstallAsyncHandler {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InstallAsyncHandlerMsg {
|
pub enum InstallAsyncHandlerMsg {
|
||||||
SetConfig(NscConfig),
|
SetConfig(NixDataConfig),
|
||||||
SetPkgTypes(SystemPkgs, UserPkgs),
|
SetPkgTypes(SystemPkgs, UserPkgs),
|
||||||
Process(WorkPkg),
|
Process(WorkPkg),
|
||||||
CancelProcess,
|
CancelProcess,
|
||||||
@ -39,11 +38,11 @@ pub struct InstallAsyncHandlerInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Worker for InstallAsyncHandler {
|
impl Worker for InstallAsyncHandler {
|
||||||
type InitParams = InstallAsyncHandlerInit;
|
type Init = InstallAsyncHandlerInit;
|
||||||
type Input = InstallAsyncHandlerMsg;
|
type Input = InstallAsyncHandlerMsg;
|
||||||
type Output = PkgMsg;
|
type Output = PkgMsg;
|
||||||
|
|
||||||
fn init(params: Self::InitParams, _sender: relm4::ComponentSender<Self>) -> Self {
|
fn init(params: Self::Init, _sender: relm4::ComponentSender<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
process: None,
|
process: None,
|
||||||
work: None,
|
work: None,
|
||||||
|
@ -2,6 +2,7 @@ use adw::gio;
|
|||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use html2pango;
|
use html2pango;
|
||||||
use image::{imageops::FilterType, ImageFormat};
|
use image::{imageops::FilterType, ImageFormat};
|
||||||
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::actions::RelmAction;
|
use relm4::actions::RelmAction;
|
||||||
use relm4::actions::RelmActionGroup;
|
use relm4::actions::RelmActionGroup;
|
||||||
use relm4::gtk::pango;
|
use relm4::gtk::pango;
|
||||||
@ -22,9 +23,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
use crate::parse::config::NscConfig;
|
|
||||||
use crate::parse::packages::PkgMaintainer;
|
use crate::parse::packages::PkgMaintainer;
|
||||||
use crate::parse::packages::StrOrVec;
|
|
||||||
use crate::ui::installworker::InstallAsyncHandlerMsg;
|
use crate::ui::installworker::InstallAsyncHandlerMsg;
|
||||||
|
|
||||||
use super::installworker::InstallAsyncHandler;
|
use super::installworker::InstallAsyncHandler;
|
||||||
@ -36,7 +35,7 @@ use super::{screenshotfactory::ScreenshotItem, window::AppMsg};
|
|||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PkgModel {
|
pub struct PkgModel {
|
||||||
config: NscConfig,
|
config: NixDataConfig,
|
||||||
name: String,
|
name: String,
|
||||||
pkg: String,
|
pkg: String,
|
||||||
pname: String,
|
pname: String,
|
||||||
@ -87,13 +86,13 @@ pub enum PkgAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Launch {
|
pub enum Launch {
|
||||||
GtkApp(String),
|
GtkApp(String),
|
||||||
TerminalApp(String),
|
TerminalApp(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum CarouselPage {
|
pub enum CarouselPage {
|
||||||
First,
|
First,
|
||||||
Middle,
|
Middle,
|
||||||
@ -107,7 +106,7 @@ pub enum InstallType {
|
|||||||
System,
|
System,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct License {
|
pub struct License {
|
||||||
pub free: Option<bool>,
|
pub free: Option<bool>,
|
||||||
pub fullname: String,
|
pub fullname: String,
|
||||||
@ -126,7 +125,7 @@ pub struct PkgInitModel {
|
|||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub screenshots: Vec<String>,
|
pub screenshots: Vec<String>,
|
||||||
pub homepage: Option<StrOrVec>,
|
pub homepage: Option<String>,
|
||||||
pub licenses: Vec<License>,
|
pub licenses: Vec<License>,
|
||||||
pub platforms: Vec<String>,
|
pub platforms: Vec<String>,
|
||||||
pub maintainers: Vec<PkgMaintainer>,
|
pub maintainers: Vec<PkgMaintainer>,
|
||||||
@ -135,7 +134,7 @@ pub struct PkgInitModel {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PkgMsg {
|
pub enum PkgMsg {
|
||||||
UpdateConfig(NscConfig),
|
UpdateConfig(NixDataConfig),
|
||||||
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
||||||
Open(Box<PkgInitModel>),
|
Open(Box<PkgInitModel>),
|
||||||
LoadScreenshot(String, usize, String),
|
LoadScreenshot(String, usize, String),
|
||||||
@ -168,7 +167,7 @@ pub enum PkgAsyncMsg {
|
|||||||
pub struct PkgPageInit {
|
pub struct PkgPageInit {
|
||||||
pub syspkgs: SystemPkgs,
|
pub syspkgs: SystemPkgs,
|
||||||
pub userpkgs: UserPkgs,
|
pub userpkgs: UserPkgs,
|
||||||
pub config: NscConfig,
|
pub config: NixDataConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
@ -1123,22 +1122,23 @@ impl Component for PkgModel {
|
|||||||
self.description = Some(pango.strip_prefix('\n').unwrap_or(&pango).to_string());
|
self.description = Some(pango.strip_prefix('\n').unwrap_or(&pango).to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(h) = pkgmodel.homepage {
|
self.homepage = pkgmodel.homepage;
|
||||||
match h {
|
// if let Some(h) = pkgmodel.homepage {
|
||||||
StrOrVec::Single(h) => {
|
// match h {
|
||||||
self.homepage = Some(h.to_string());
|
// StrOrVec::Single(h) => {
|
||||||
}
|
// self.homepage = Some(h.to_string());
|
||||||
StrOrVec::List(h) => {
|
// }
|
||||||
if let Some(first) = h.get(0) {
|
// StrOrVec::List(h) => {
|
||||||
self.homepage = Some(first.to_string());
|
// if let Some(first) = h.get(0) {
|
||||||
} else {
|
// self.homepage = Some(first.to_string());
|
||||||
self.homepage = None;
|
// } else {
|
||||||
}
|
// self.homepage = None;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} else {
|
// }
|
||||||
self.homepage = None;
|
// } else {
|
||||||
}
|
// self.homepage = None;
|
||||||
|
// }
|
||||||
|
|
||||||
if pkgmodel.screenshots.len() <= 1 {
|
if pkgmodel.screenshots.len() <= 1 {
|
||||||
self.carpage = CarouselPage::Single;
|
self.carpage = CarouselPage::Single;
|
||||||
@ -1150,14 +1150,14 @@ impl Component for PkgModel {
|
|||||||
let mut scrn_guard = self.screenshots.guard();
|
let mut scrn_guard = self.screenshots.guard();
|
||||||
scrn_guard.clear();
|
scrn_guard.clear();
|
||||||
for _i in 0..pkgmodel.screenshots.len() {
|
for _i in 0..pkgmodel.screenshots.len() {
|
||||||
scrn_guard.push_back(())
|
scrn_guard.push_back(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, url) in pkgmodel.screenshots.into_iter().enumerate() {
|
for (i, url) in pkgmodel.screenshots.into_iter().enumerate() {
|
||||||
if let Ok(home) = env::var("HOME") {
|
if let Ok(home) = env::var("HOME") {
|
||||||
let cachedir = format!("{}/.cache/nix-software-center", home);
|
let cachedir = format!("{}/.cache/nix-software-center", home);
|
||||||
let sha = digest(&url);
|
let sha = digest(url.to_string());
|
||||||
let scrnpath = format!("{}/screenshots/{}", cachedir, sha);
|
let scrnpath = format!("{}/screenshots/{}", cachedir, sha);
|
||||||
let pkg = self.pkg.clone();
|
let pkg = self.pkg.clone();
|
||||||
|
|
||||||
@ -1289,13 +1289,13 @@ impl Component for PkgModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PkgMsg::Close => {
|
PkgMsg::Close => {
|
||||||
self.pkg = String::default();
|
// self.pkg = String::default();
|
||||||
self.name = String::default();
|
// self.name = String::default();
|
||||||
self.summary = None;
|
// self.summary = None;
|
||||||
self.description = None;
|
// self.description = None;
|
||||||
self.icon = None;
|
// self.icon = None;
|
||||||
let mut scrn_guard = self.screenshots.guard();
|
// let mut scrn_guard = self.screenshots.guard();
|
||||||
scrn_guard.clear();
|
// scrn_guard.clear();
|
||||||
sender.output(AppMsg::FrontPage)
|
sender.output(AppMsg::FrontPage)
|
||||||
}
|
}
|
||||||
PkgMsg::InstallUser => {
|
PkgMsg::InstallUser => {
|
||||||
@ -1391,10 +1391,11 @@ impl Component for PkgModel {
|
|||||||
self.installedsystempkgs.remove(&work.pkg);
|
self.installedsystempkgs.remove(&work.pkg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sender.output(AppMsg::UpdateUpdatePkgs);
|
// sender.output(AppMsg::UpdateUpdatePkgs);
|
||||||
|
// sender.output(AppMsg::UpdateInstalledPkgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sender.output(AppMsg::UpdatePkgs(None));
|
sender.output(AppMsg::UpdateInstalledPkgs);
|
||||||
if let Some(n) = &work.notify {
|
if let Some(n) = &work.notify {
|
||||||
match n {
|
match n {
|
||||||
NotifyPage::Installed => {
|
NotifyPage::Installed => {
|
||||||
@ -1556,29 +1557,7 @@ impl Component for PkgModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn launchterm(cmd: &str) {
|
fn launchterm(cmd: &str) {
|
||||||
if which::which("kgx").is_ok() {
|
let _ = Command::new("kgx").arg("-e").arg(&cmd).spawn();
|
||||||
let _ = Command::new("kgx").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("gnome-terminal").is_ok() {
|
|
||||||
let _ = Command::new("gnome-terminal").arg("--").arg(&cmd).spawn();
|
|
||||||
} else if which::which("konsole").is_ok() {
|
|
||||||
let _ = Command::new("konsole").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("mate-terminal").is_ok() {
|
|
||||||
let _ = Command::new("mate-terminal").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("xfce4-terminal").is_ok() {
|
|
||||||
let _ = Command::new("xfce4-terminal").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("tilix").is_ok() {
|
|
||||||
let _ = Command::new("tilix").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("terminology").is_ok() {
|
|
||||||
let _ = Command::new("terminology").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("alacritty").is_ok() {
|
|
||||||
let _ = Command::new("alacritty").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("urxvt").is_ok() {
|
|
||||||
let _ = Command::new("urxvt").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else if which::which("xterm").is_ok() {
|
|
||||||
let _ = Command::new("xterm").arg("-e").arg(&cmd).spawn();
|
|
||||||
} else {
|
|
||||||
error!("No terminal detected!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
relm4::new_action_group!(ModeActionGroup, "mode");
|
relm4::new_action_group!(ModeActionGroup, "mode");
|
||||||
|
@ -8,7 +8,7 @@ use crate::APPINFO;
|
|||||||
|
|
||||||
use super::window::AppMsg;
|
use super::window::AppMsg;
|
||||||
|
|
||||||
#[derive(Default, Debug, PartialEq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
pub struct PkgTile {
|
pub struct PkgTile {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub pkg: String,
|
pub pkg: String,
|
||||||
@ -32,7 +32,7 @@ impl FactoryComponent for PkgTile {
|
|||||||
type Output = PkgTileMsg;
|
type Output = PkgTileMsg;
|
||||||
type Widgets = PkgTileWidgets;
|
type Widgets = PkgTileWidgets;
|
||||||
type ParentWidget = gtk::FlowBox;
|
type ParentWidget = gtk::FlowBox;
|
||||||
type ParentMsg = AppMsg;
|
type ParentInput = AppMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
gtk::FlowBoxChild {
|
gtk::FlowBoxChild {
|
||||||
@ -171,7 +171,7 @@ impl FactoryComponent for PkgTile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_to_parent_msg(output: Self::Output) -> Option<AppMsg> {
|
fn output_to_parent_input(output: Self::Output) -> Option<AppMsg> {
|
||||||
Some(match output {
|
Some(match output {
|
||||||
PkgTileMsg::Open(x) => AppMsg::OpenPkg(x),
|
PkgTileMsg::Open(x) => AppMsg::OpenPkg(x),
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::parse::config::NscConfig;
|
|
||||||
|
|
||||||
use super::window::AppMsg;
|
use super::window::AppMsg;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
use relm4_components::open_dialog::*;
|
use relm4_components::open_dialog::*;
|
||||||
|
|
||||||
@ -22,7 +20,7 @@ pub struct PreferencesPageModel {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PreferencesPageMsg {
|
pub enum PreferencesPageMsg {
|
||||||
Show(NscConfig),
|
Show(NixDataConfig),
|
||||||
Open,
|
Open,
|
||||||
OpenFlake,
|
OpenFlake,
|
||||||
SetConfigPath(Option<PathBuf>),
|
SetConfigPath(Option<PathBuf>),
|
||||||
@ -34,7 +32,7 @@ pub enum PreferencesPageMsg {
|
|||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for PreferencesPageModel {
|
impl SimpleComponent for PreferencesPageModel {
|
||||||
type InitParams = gtk::Window;
|
type Init = gtk::Window;
|
||||||
type Input = PreferencesPageMsg;
|
type Input = PreferencesPageMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = PreferencesPageWidgets;
|
type Widgets = PreferencesPageWidgets;
|
||||||
@ -165,7 +163,7 @@ impl SimpleComponent for PreferencesPageModel {
|
|||||||
} @flakeentry,
|
} @flakeentry,
|
||||||
#[track(model.changed(PreferencesPageModel::flake()))]
|
#[track(model.changed(PreferencesPageModel::flake()))]
|
||||||
#[block_signal(flakeentry)]
|
#[block_signal(flakeentry)]
|
||||||
set_text: &model.flakearg.as_ref().unwrap_or(&String::new())
|
set_text: model.flakearg.as_ref().unwrap_or(&String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -174,21 +172,21 @@ impl SimpleComponent for PreferencesPageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
parent_window: Self::InitParams,
|
parent_window: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let open_dialog = OpenDialog::builder()
|
let open_dialog = OpenDialog::builder()
|
||||||
.transient_for_native(root)
|
.transient_for_native(root)
|
||||||
.launch(OpenDialogSettings::default())
|
.launch(OpenDialogSettings::default())
|
||||||
.forward(&sender.input, |response| match response {
|
.forward(sender.input_sender(), |response| match response {
|
||||||
OpenDialogResponse::Accept(path) => PreferencesPageMsg::SetConfigPath(Some(path)),
|
OpenDialogResponse::Accept(path) => PreferencesPageMsg::SetConfigPath(Some(path)),
|
||||||
OpenDialogResponse::Cancel => PreferencesPageMsg::Ignore,
|
OpenDialogResponse::Cancel => PreferencesPageMsg::Ignore,
|
||||||
});
|
});
|
||||||
let flake_file_dialog = OpenDialog::builder()
|
let flake_file_dialog = OpenDialog::builder()
|
||||||
.transient_for_native(root)
|
.transient_for_native(root)
|
||||||
.launch(OpenDialogSettings::default())
|
.launch(OpenDialogSettings::default())
|
||||||
.forward(&sender.input, |response| match response {
|
.forward(sender.input_sender(), |response| match response {
|
||||||
OpenDialogResponse::Accept(path) => PreferencesPageMsg::SetFlakePath(Some(path)),
|
OpenDialogResponse::Accept(path) => PreferencesPageMsg::SetFlakePath(Some(path)),
|
||||||
OpenDialogResponse::Cancel => PreferencesPageMsg::Ignore,
|
OpenDialogResponse::Cancel => PreferencesPageMsg::Ignore,
|
||||||
});
|
});
|
||||||
@ -211,9 +209,9 @@ impl SimpleComponent for PreferencesPageModel {
|
|||||||
self.reset();
|
self.reset();
|
||||||
match msg {
|
match msg {
|
||||||
PreferencesPageMsg::Show(config) => {
|
PreferencesPageMsg::Show(config) => {
|
||||||
self.configpath = config.systemconfig.as_ref().map(|x| PathBuf::from(x));
|
self.configpath = config.systemconfig.as_ref().map(PathBuf::from);
|
||||||
self.set_flake(config.flake.as_ref().map(|x| PathBuf::from(x)));
|
self.set_flake(config.flake.as_ref().map(PathBuf::from));
|
||||||
self.set_flakearg(config.flakearg.clone());
|
self.set_flakearg(config.flakearg);
|
||||||
self.hidden = false;
|
self.hidden = false;
|
||||||
}
|
}
|
||||||
PreferencesPageMsg::Open => self.open_dialog.emit(OpenDialogMsg::Open),
|
PreferencesPageMsg::Open => self.open_dialog.emit(OpenDialogMsg::Open),
|
||||||
|
@ -3,7 +3,7 @@ use relm4::{factory::*, *};
|
|||||||
|
|
||||||
use super::pkgpage::PkgMsg;
|
use super::pkgpage::PkgMsg;
|
||||||
|
|
||||||
#[derive(Default, Debug, PartialEq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
pub struct ScreenshotItem {
|
pub struct ScreenshotItem {
|
||||||
pub path: Option<String>,
|
pub path: Option<String>,
|
||||||
pub error: bool,
|
pub error: bool,
|
||||||
@ -20,7 +20,7 @@ impl FactoryComponent for ScreenshotItem {
|
|||||||
type Output = ScreenshotItemMsg;
|
type Output = ScreenshotItemMsg;
|
||||||
type Widgets = PkgTileWidgets;
|
type Widgets = PkgTileWidgets;
|
||||||
type ParentWidget = adw::Carousel;
|
type ParentWidget = adw::Carousel;
|
||||||
type ParentMsg = PkgMsg;
|
type ParentInput = PkgMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
|
@ -25,7 +25,7 @@ pub enum SearchPageMsg {
|
|||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for SearchPageModel {
|
impl SimpleComponent for SearchPageModel {
|
||||||
type InitParams = ();
|
type Init = ();
|
||||||
type Input = SearchPageMsg;
|
type Input = SearchPageMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = SearchPageWidgets;
|
type Widgets = SearchPageWidgets;
|
||||||
@ -53,12 +53,12 @@ impl SimpleComponent for SearchPageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
(): Self::InitParams,
|
(): Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
let model = SearchPageModel {
|
let model = SearchPageModel {
|
||||||
searchitems: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
|
searchitems: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
searchitemtracker: 0,
|
searchitemtracker: 0,
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
@ -110,7 +110,7 @@ impl SimpleComponent for SearchPageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, PartialEq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
pub struct SearchItem {
|
pub struct SearchItem {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub pkg: String,
|
pub pkg: String,
|
||||||
@ -122,7 +122,7 @@ pub struct SearchItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
#[derive(Default, Debug, PartialEq)]
|
#[derive(Default, Debug, PartialEq, Eq)]
|
||||||
pub struct SearchItemModel {
|
pub struct SearchItemModel {
|
||||||
pub item: SearchItem,
|
pub item: SearchItem,
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ impl FactoryComponent for SearchItemModel {
|
|||||||
type Output = SearchItemMsg;
|
type Output = SearchItemMsg;
|
||||||
type Widgets = SearchItemWidgets;
|
type Widgets = SearchItemWidgets;
|
||||||
type ParentWidget = adw::gtk::ListBox;
|
type ParentWidget = adw::gtk::ListBox;
|
||||||
type ParentMsg = SearchPageMsg;
|
type ParentInput = SearchPageMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
adw::PreferencesRow {
|
adw::PreferencesRow {
|
||||||
|
@ -21,7 +21,7 @@ pub enum UpdateDialogMsg {
|
|||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for UpdateDialogModel {
|
impl SimpleComponent for UpdateDialogModel {
|
||||||
type InitParams = gtk::Window;
|
type Init = gtk::Window;
|
||||||
type Input = UpdateDialogMsg;
|
type Input = UpdateDialogMsg;
|
||||||
type Output = UpdatePageMsg;
|
type Output = UpdatePageMsg;
|
||||||
type Widgets = UpdateDialogWidgets;
|
type Widgets = UpdateDialogWidgets;
|
||||||
@ -99,7 +99,7 @@ impl SimpleComponent for UpdateDialogModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
parent_window: Self::InitParams,
|
parent_window: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use crate::{parse::{cache::channelver, config::NscConfig}, APPINFO};
|
use crate::APPINFO;
|
||||||
|
|
||||||
use super::{pkgpage::InstallType, window::*, updatedialog::{UpdateDialogModel, UpdateDialogMsg}, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}};
|
use super::{pkgpage::InstallType, window::*, updatedialog::{UpdateDialogModel, UpdateDialogMsg}, updateworker::{UpdateAsyncHandler, UpdateAsyncHandlerMsg, UpdateAsyncHandlerInit}};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
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};
|
||||||
use log::*;
|
use log::*;
|
||||||
@ -18,7 +19,7 @@ pub struct UpdatePageModel {
|
|||||||
updatedialog: Controller<UpdateDialogModel>,
|
updatedialog: Controller<UpdateDialogModel>,
|
||||||
#[tracker::no_eq]
|
#[tracker::no_eq]
|
||||||
updateworker: WorkerController<UpdateAsyncHandler>,
|
updateworker: WorkerController<UpdateAsyncHandler>,
|
||||||
config: NscConfig,
|
config: NixDataConfig,
|
||||||
systype: SystemPkgs,
|
systype: SystemPkgs,
|
||||||
usertype: UserPkgs,
|
usertype: UserPkgs,
|
||||||
updatetracker: u8,
|
updatetracker: u8,
|
||||||
@ -26,7 +27,7 @@ pub struct UpdatePageModel {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum UpdatePageMsg {
|
pub enum UpdatePageMsg {
|
||||||
UpdateConfig(NscConfig),
|
UpdateConfig(NixDataConfig),
|
||||||
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
||||||
Update(Vec<UpdateItem>, Vec<UpdateItem>),
|
Update(Vec<UpdateItem>, Vec<UpdateItem>),
|
||||||
OpenRow(usize, InstallType),
|
OpenRow(usize, InstallType),
|
||||||
@ -45,12 +46,12 @@ pub struct UpdatePageInit {
|
|||||||
pub window: gtk::Window,
|
pub window: gtk::Window,
|
||||||
pub systype: SystemPkgs,
|
pub systype: SystemPkgs,
|
||||||
pub usertype: UserPkgs,
|
pub usertype: UserPkgs,
|
||||||
pub config: NscConfig,
|
pub config: NixDataConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for UpdatePageModel {
|
impl SimpleComponent for UpdatePageModel {
|
||||||
type InitParams = UpdatePageInit;
|
type Init = UpdatePageInit;
|
||||||
type Input = UpdatePageMsg;
|
type Input = UpdatePageMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = UpdatePageWidgets;
|
type Widgets = UpdatePageWidgets;
|
||||||
@ -277,7 +278,7 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
initparams: Self::InitParams,
|
initparams: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
@ -292,8 +293,8 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(config.clone()));
|
updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(config.clone()));
|
||||||
|
|
||||||
let model = UpdatePageModel {
|
let model = UpdatePageModel {
|
||||||
updateuserlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
|
updateuserlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
updatesystemlist: FactoryVecDeque::new(gtk::ListBox::new(), &sender.input),
|
updatesystemlist: FactoryVecDeque::new(gtk::ListBox::new(), sender.input_sender()),
|
||||||
channelupdate: None,
|
channelupdate: None,
|
||||||
updatetracker: 0,
|
updatetracker: 0,
|
||||||
updatedialog,
|
updatedialog,
|
||||||
@ -320,15 +321,21 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(self.config.clone()));
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateConfig(self.config.clone()));
|
||||||
}
|
}
|
||||||
UpdatePageMsg::UpdatePkgTypes(systype, usertype) => {
|
UpdatePageMsg::UpdatePkgTypes(systype, usertype) => {
|
||||||
self.systype = systype.clone();
|
self.systype = systype;
|
||||||
self.usertype = usertype.clone();
|
self.usertype = usertype;
|
||||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdatePkgTypes(self.systype.clone(), self.usertype.clone()));
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdatePkgTypes(self.systype.clone(), self.usertype.clone()));
|
||||||
}
|
}
|
||||||
UpdatePageMsg::Update(updateuserlist, updatesystemlist) => {
|
UpdatePageMsg::Update(updateuserlist, updatesystemlist) => {
|
||||||
info!("UpdatePageMsg::Update");
|
info!("UpdatePageMsg::Update");
|
||||||
debug!("UPDATEUSERLIST: {:?}", updateuserlist);
|
debug!("UPDATEUSERLIST: {:?}", updateuserlist);
|
||||||
debug!("UPDATESYSTEMLIST: {:?}", updatesystemlist);
|
debug!("UPDATESYSTEMLIST: {:?}", updatesystemlist);
|
||||||
self.channelupdate = channelver().unwrap_or(None);
|
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();
|
||||||
@ -384,7 +391,7 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateAll);
|
self.updateworker.emit(UpdateAsyncHandlerMsg::UpdateAll);
|
||||||
}
|
}
|
||||||
UpdatePageMsg::DoneWorking => {
|
UpdatePageMsg::DoneWorking => {
|
||||||
sender.output(AppMsg::ReloadUpdate);
|
sender.output(AppMsg::UpdateInstalledPkgs);
|
||||||
}
|
}
|
||||||
UpdatePageMsg::DoneLoading => {
|
UpdatePageMsg::DoneLoading => {
|
||||||
self.updatedialog.emit(UpdateDialogMsg::Done);
|
self.updatedialog.emit(UpdateDialogMsg::Done);
|
||||||
@ -396,7 +403,7 @@ impl SimpleComponent for UpdatePageModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct UpdateItem {
|
pub struct UpdateItem {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub pkg: Option<String>,
|
pub pkg: Option<String>,
|
||||||
@ -408,7 +415,7 @@ pub struct UpdateItem {
|
|||||||
pub verto: Option<String>,
|
pub verto: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct UpdateItemModel {
|
pub struct UpdateItemModel {
|
||||||
item: UpdateItem,
|
item: UpdateItem,
|
||||||
}
|
}
|
||||||
@ -424,7 +431,7 @@ impl FactoryComponent for UpdateItemModel {
|
|||||||
type Output = UpdateItemMsg;
|
type Output = UpdateItemMsg;
|
||||||
type Widgets = UpdateItemWidgets;
|
type Widgets = UpdateItemWidgets;
|
||||||
type ParentWidget = adw::gtk::ListBox;
|
type ParentWidget = adw::gtk::ListBox;
|
||||||
type ParentMsg = UpdatePageMsg;
|
type ParentInput = UpdatePageMsg;
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
adw::PreferencesRow {
|
adw::PreferencesRow {
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
use std::{error::Error, path::Path, process::Stdio};
|
use std::{error::Error, path::Path, process::Stdio};
|
||||||
use tokio::io::AsyncBufReadExt;
|
use tokio::io::AsyncBufReadExt;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
use crate::parse::config::NscConfig;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
updatepage::UpdatePageMsg,
|
updatepage::UpdatePageMsg,
|
||||||
window::{SystemPkgs, UserPkgs},
|
window::{SystemPkgs, UserPkgs},
|
||||||
@ -23,7 +22,7 @@ pub struct UpdateAsyncHandler {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum UpdateAsyncHandlerMsg {
|
pub enum UpdateAsyncHandlerMsg {
|
||||||
UpdateConfig(NscConfig),
|
UpdateConfig(NixDataConfig),
|
||||||
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
UpdatePkgTypes(SystemPkgs, UserPkgs),
|
||||||
|
|
||||||
UpdateChannels,
|
UpdateChannels,
|
||||||
@ -47,11 +46,11 @@ pub struct UpdateAsyncHandlerInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Worker for UpdateAsyncHandler {
|
impl Worker for UpdateAsyncHandler {
|
||||||
type InitParams = UpdateAsyncHandlerInit;
|
type Init = UpdateAsyncHandlerInit;
|
||||||
type Input = UpdateAsyncHandlerMsg;
|
type Input = UpdateAsyncHandlerMsg;
|
||||||
type Output = UpdatePageMsg;
|
type Output = UpdatePageMsg;
|
||||||
|
|
||||||
fn init(params: Self::InitParams, _sender: relm4::ComponentSender<Self>) -> Self {
|
fn init(params: Self::Init, _sender: relm4::ComponentSender<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
process: None,
|
process: None,
|
||||||
systemconfig: None,
|
systemconfig: None,
|
||||||
|
@ -2,11 +2,10 @@ use std::path::{PathBuf, Path};
|
|||||||
|
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
use relm4_components::open_dialog::*;
|
use relm4_components::open_dialog::*;
|
||||||
|
|
||||||
use crate::parse::config::NscConfig;
|
|
||||||
|
|
||||||
use super::window::AppMsg;
|
use super::window::AppMsg;
|
||||||
|
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
@ -36,7 +35,7 @@ pub enum WelcomeMsg {
|
|||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for WelcomeModel {
|
impl SimpleComponent for WelcomeModel {
|
||||||
type InitParams = gtk::Window;
|
type Init = gtk::Window;
|
||||||
type Input = WelcomeMsg;
|
type Input = WelcomeMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = WelcomeWidgets;
|
type Widgets = WelcomeWidgets;
|
||||||
@ -176,7 +175,7 @@ impl SimpleComponent for WelcomeModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
parent_window: Self::InitParams,
|
parent_window: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
@ -184,7 +183,7 @@ impl SimpleComponent for WelcomeModel {
|
|||||||
let conf_dialog = OpenDialog::builder()
|
let conf_dialog = OpenDialog::builder()
|
||||||
.transient_for_native(root)
|
.transient_for_native(root)
|
||||||
.launch(OpenDialogSettings::default())
|
.launch(OpenDialogSettings::default())
|
||||||
.forward(&sender.input, |response| match response {
|
.forward(sender.input_sender(), |response| match response {
|
||||||
OpenDialogResponse::Accept(path) => WelcomeMsg::UpdateConfPath(path),
|
OpenDialogResponse::Accept(path) => WelcomeMsg::UpdateConfPath(path),
|
||||||
OpenDialogResponse::Cancel => WelcomeMsg::Ignore,
|
OpenDialogResponse::Cancel => WelcomeMsg::Ignore,
|
||||||
});
|
});
|
||||||
@ -193,7 +192,7 @@ impl SimpleComponent for WelcomeModel {
|
|||||||
let flake_dialog = OpenDialog::builder()
|
let flake_dialog = OpenDialog::builder()
|
||||||
.transient_for_native(root)
|
.transient_for_native(root)
|
||||||
.launch(OpenDialogSettings::default())
|
.launch(OpenDialogSettings::default())
|
||||||
.forward(&sender.input, |response| match response {
|
.forward(sender.input_sender(), |response| match response {
|
||||||
OpenDialogResponse::Accept(path) => WelcomeMsg::UpdateFlakePath(path),
|
OpenDialogResponse::Accept(path) => WelcomeMsg::UpdateFlakePath(path),
|
||||||
OpenDialogResponse::Cancel => WelcomeMsg::Ignore,
|
OpenDialogResponse::Cancel => WelcomeMsg::Ignore,
|
||||||
});
|
});
|
||||||
@ -222,7 +221,7 @@ impl SimpleComponent for WelcomeModel {
|
|||||||
self.hidden = false;
|
self.hidden = false;
|
||||||
}
|
}
|
||||||
WelcomeMsg::Close => {
|
WelcomeMsg::Close => {
|
||||||
let config = NscConfig {
|
let config = NixDataConfig {
|
||||||
systemconfig: self.confpath.as_ref().map(|x| x.to_string_lossy().to_string()),
|
systemconfig: self.confpath.as_ref().map(|x| x.to_string_lossy().to_string()),
|
||||||
flake: self.flakepath.as_ref().map(|x| x.to_string_lossy().to_string()),
|
flake: self.flakepath.as_ref().map(|x| x.to_string_lossy().to_string()),
|
||||||
flakearg: None,
|
flakearg: None,
|
||||||
|
1839
src/ui/window.rs
1839
src/ui/window.rs
File diff suppressed because it is too large
Load Diff
@ -1,423 +1,375 @@
|
|||||||
use super::window::AppMsg;
|
use super::window::AppMsg;
|
||||||
use super::window::SystemPkgs;
|
use super::window::SystemPkgs;
|
||||||
use crate::parse::cache::checkcache;
|
use crate::parse::packages::appsteamdata;
|
||||||
use crate::parse::config::NscConfig;
|
use crate::parse::packages::AppData;
|
||||||
use crate::parse::packages::readflakesyspkgs;
|
|
||||||
use crate::parse::packages::readpkgs;
|
|
||||||
use crate::parse::packages::readlegacysyspkgs;
|
|
||||||
use crate::parse::packages::Package;
|
|
||||||
use crate::parse::packages::readprofilepkgs;
|
|
||||||
use crate::ui::categories::PkgCategory;
|
use crate::ui::categories::PkgCategory;
|
||||||
use crate::ui::window::UserPkgs;
|
use crate::ui::window::UserPkgs;
|
||||||
|
use log::*;
|
||||||
|
use nix_data::config::configfile::NixDataConfig;
|
||||||
use rand::prelude::SliceRandom;
|
use rand::prelude::SliceRandom;
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use relm4::adw::prelude::*;
|
use relm4::adw::prelude::*;
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
use std::{collections::HashMap, env};
|
use std::{collections::HashMap, env};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use log::*;
|
|
||||||
|
|
||||||
pub struct WindowAsyncHandler;
|
pub struct WindowAsyncHandler;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum WindowAsyncHandlerMsg {
|
pub enum WindowAsyncHandlerMsg {
|
||||||
CheckCache(CacheReturn, SystemPkgs, UserPkgs, NscConfig),
|
CheckCache(SystemPkgs, UserPkgs, NixDataConfig),
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum CacheReturn {
|
|
||||||
Init,
|
|
||||||
Update,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Worker for WindowAsyncHandler {
|
impl Worker for WindowAsyncHandler {
|
||||||
type InitParams = ();
|
type Init = ();
|
||||||
type Input = WindowAsyncHandlerMsg;
|
type Input = WindowAsyncHandlerMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
|
|
||||||
fn init(_params: Self::InitParams, _sender: relm4::ComponentSender<Self>) -> Self {
|
fn init(_params: Self::Init, _sender: relm4::ComponentSender<Self>) -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
|
||||||
match msg {
|
match msg {
|
||||||
WindowAsyncHandlerMsg::CheckCache(cr, syspkgs, userpkgs, config) => {
|
WindowAsyncHandlerMsg::CheckCache(syspkgs, userpkgs, _config) => {
|
||||||
info!("WindowAsyncHandlerMsg::CheckCache");
|
info!("WindowAsyncHandlerMsg::CheckCache");
|
||||||
let syspkgs2 = syspkgs.clone();
|
|
||||||
let userpkgs2 = userpkgs.clone();
|
|
||||||
let config = config.clone();
|
|
||||||
relm4::spawn(async move {
|
relm4::spawn(async move {
|
||||||
match checkcache(syspkgs2, userpkgs2, config) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
warn!("FAILED TO CHECK CACHE");
|
|
||||||
warn!("{}", e);
|
|
||||||
sender.output(AppMsg::LoadError(
|
|
||||||
String::from("Could not load cache"),
|
|
||||||
String::from(
|
|
||||||
"Try connecting to the internet or launching the application again",
|
|
||||||
),
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let pkgs = match readpkgs().await {
|
|
||||||
Ok(pkgs) => pkgs,
|
|
||||||
Err(e) => {
|
|
||||||
warn!("FAILED TO LOAD PKGS");
|
|
||||||
warn!("{}", e);
|
|
||||||
sender.output(AppMsg::LoadError(
|
|
||||||
String::from("Could not load packages"),
|
|
||||||
String::from(
|
|
||||||
"Try connecting to the internet or launching the application again",
|
|
||||||
),
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let newpkgs = match syspkgs {
|
|
||||||
SystemPkgs::Legacy => {
|
|
||||||
match readlegacysyspkgs() {
|
|
||||||
Ok(newpkgs) => newpkgs,
|
|
||||||
Err(e) => {
|
|
||||||
warn!("FAILED TO LOAD NEW PKGS");
|
|
||||||
warn!("{}", e);
|
|
||||||
sender.output(AppMsg::LoadError(
|
|
||||||
String::from("Could not load new packages"),
|
|
||||||
String::from(
|
|
||||||
"Try connecting to the internet or launching the application again",
|
|
||||||
),
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SystemPkgs::Flake => {
|
|
||||||
match readflakesyspkgs() {
|
|
||||||
Ok(newpkgs) => newpkgs,
|
|
||||||
Err(e) => {
|
|
||||||
warn!("FAILED TO LOAD NEW PKGS");
|
|
||||||
warn!("{}", e);
|
|
||||||
sender.output(AppMsg::LoadError(
|
|
||||||
String::from("Could not load new packages"),
|
|
||||||
String::from(
|
|
||||||
"Try connecting to the internet or launching the application again",
|
|
||||||
),
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SystemPkgs::None => {
|
|
||||||
HashMap::new()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let profilepkgs = match userpkgs {
|
|
||||||
UserPkgs::Env => None,
|
|
||||||
UserPkgs::Profile => if let Ok(r) = readprofilepkgs() { Some(r) } else { None },
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut recpicks = vec![];
|
let mut recpicks = vec![];
|
||||||
let mut catpicks: HashMap<PkgCategory, Vec<String>> = HashMap::new();
|
let mut catpicks: HashMap<PkgCategory, Vec<String>> = HashMap::new();
|
||||||
let mut catpkgs: HashMap<PkgCategory, Vec<String>> = HashMap::new();
|
let mut catpkgs: HashMap<PkgCategory, Vec<String>> = HashMap::new();
|
||||||
|
println!("Connecting to DB");
|
||||||
|
|
||||||
|
let pkgdb = nix_data::cache::nixos::nixospkgs().await.unwrap();
|
||||||
|
let pool = SqlitePool::connect(&format!("sqlite://{}", pkgdb))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if cr == CacheReturn::Init {
|
let nixpkgsdb = match userpkgs {
|
||||||
let desktopenv = env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
|
UserPkgs::Profile => {
|
||||||
let appdatapkgs = pkgs
|
if let Ok(x) = nix_data::cache::profile::nixpkgslatest().await {
|
||||||
.iter()
|
Some(x)
|
||||||
.filter(|(x, _)| {
|
} else {
|
||||||
if let Some(p) = pkgs.get(*x) {
|
None
|
||||||
if let Some(data) = &p.appdata {
|
}
|
||||||
(if let Some(i) = &data.icon {
|
|
||||||
i.cached.is_some()
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}) && data.description.is_some()
|
|
||||||
&& data.name.is_some()
|
|
||||||
&& data.launchable.is_some()
|
|
||||||
&& data.screenshots.is_some()
|
|
||||||
&& (!x.starts_with("gnome.") || desktopenv == "GNOME")
|
|
||||||
&& (!x.starts_with("xfce.") || desktopenv == "XFCE")
|
|
||||||
&& (!x.starts_with("mate.") || desktopenv == "MATE")
|
|
||||||
&& (!x.starts_with("cinnamon.")
|
|
||||||
|| desktopenv == "X-Cinnamon")
|
|
||||||
&& (!x.starts_with("libsForQt5") || desktopenv == "KDE")
|
|
||||||
&& (!x.starts_with("pantheon.")
|
|
||||||
|| desktopenv == "Pantheon")
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<HashMap<_, _>>();
|
|
||||||
|
|
||||||
let mut recommendedpkgs = appdatapkgs
|
|
||||||
.keys()
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
recommendedpkgs.shuffle(&mut rng);
|
|
||||||
|
|
||||||
let mut desktoppicks = recommendedpkgs
|
|
||||||
.iter()
|
|
||||||
.filter(|x| {
|
|
||||||
if desktopenv == "GNOME" {
|
|
||||||
x.starts_with("gnome.") || x.starts_with("gnome-")
|
|
||||||
} else if desktopenv == "XFCE" {
|
|
||||||
x.starts_with("xfce.")
|
|
||||||
} else if desktopenv == "MATE" {
|
|
||||||
x.starts_with("mate.")
|
|
||||||
} else if desktopenv == "X-Cinnamon" {
|
|
||||||
x.starts_with("cinnamon.")
|
|
||||||
} else if desktopenv == "KDE" {
|
|
||||||
x.starts_with("libsForQt5")
|
|
||||||
} else if desktopenv == "Pantheon" {
|
|
||||||
x.starts_with("pantheon.")
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
for p in desktoppicks.iter().take(3) {
|
|
||||||
recpicks.push(p.to_string());
|
|
||||||
}
|
}
|
||||||
for category in PkgCategory::iter() {
|
UserPkgs::Env => None,
|
||||||
desktoppicks.shuffle(&mut rng);
|
};
|
||||||
let mut cvec = vec![];
|
|
||||||
let mut allvec = vec![];
|
let systemdb = match syspkgs {
|
||||||
let mut rpkgs = recommendedpkgs.clone();
|
SystemPkgs::None => None,
|
||||||
fn checkpkgs(
|
SystemPkgs::Legacy => {
|
||||||
pkg: String,
|
if let Ok(x) = nix_data::cache::channel::legacypkgs().await {
|
||||||
pkgs: &HashMap<&String, &Package>,
|
Some(x)
|
||||||
category: PkgCategory,
|
} else {
|
||||||
) -> bool {
|
None
|
||||||
match category {
|
}
|
||||||
PkgCategory::Audio => {
|
}
|
||||||
// Audio:
|
SystemPkgs::Flake => {
|
||||||
// - pkgs/applications/audio
|
if let Ok(x) = nix_data::cache::flakes::flakespkgs().await {
|
||||||
if let Some(p) = pkgs.get(&pkg) {
|
Some(x)
|
||||||
if let Some(pos) = &p.meta.position {
|
} else {
|
||||||
if pos.starts_with("pkgs/applications/audio") {
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let pkglist: Vec<(String,)> = sqlx::query_as("SELECT attribute FROM pkgs")
|
||||||
|
.fetch_all(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let pkglist = pkglist.iter().map(|x| x.0.clone()).collect::<Vec<String>>();
|
||||||
|
|
||||||
|
let posvec: Vec<(String, String)> =
|
||||||
|
sqlx::query_as("SELECT attribute, position FROM meta")
|
||||||
|
.fetch_all(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
println!("Got DB data");
|
||||||
|
let appdata = appsteamdata().unwrap();
|
||||||
|
|
||||||
|
let desktopenv = env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
|
||||||
|
|
||||||
|
let mut recpkgs = pkglist
|
||||||
|
.iter()
|
||||||
|
.filter(|x| {
|
||||||
|
if let Some(data) = appdata.get(&x.to_string()) {
|
||||||
|
(if let Some(i) = &data.icon {
|
||||||
|
i.cached.is_some()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}) && data.description.is_some()
|
||||||
|
&& data.name.is_some()
|
||||||
|
&& data.launchable.is_some()
|
||||||
|
&& data.screenshots.is_some()
|
||||||
|
&& (!x.starts_with("gnome.") || desktopenv == "GNOME")
|
||||||
|
&& (!x.starts_with("xfce.") || desktopenv == "XFCE")
|
||||||
|
&& (!x.starts_with("mate.") || desktopenv == "MATE")
|
||||||
|
&& (!x.starts_with("cinnamon.") || desktopenv == "X-Cinnamon")
|
||||||
|
&& (!x.starts_with("libsForQt5") || desktopenv == "KDE")
|
||||||
|
&& (!x.starts_with("pantheon.") || desktopenv == "Pantheon")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
recpkgs.shuffle(&mut rng);
|
||||||
|
|
||||||
|
let mut desktoppicks = recpkgs
|
||||||
|
.iter()
|
||||||
|
.filter(|x| {
|
||||||
|
if desktopenv == "GNOME" {
|
||||||
|
x.starts_with("gnome.") || x.starts_with("gnome-")
|
||||||
|
} else if desktopenv == "XFCE" {
|
||||||
|
x.starts_with("xfce.")
|
||||||
|
} else if desktopenv == "MATE" {
|
||||||
|
x.starts_with("mate.")
|
||||||
|
} else if desktopenv == "X-Cinnamon" {
|
||||||
|
x.starts_with("cinnamon.")
|
||||||
|
} else if desktopenv == "KDE" {
|
||||||
|
x.starts_with("libsForQt5")
|
||||||
|
} else if desktopenv == "Pantheon" {
|
||||||
|
x.starts_with("pantheon.")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for p in desktoppicks.iter().take(3) {
|
||||||
|
recpicks.push(p.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let pospkgs = posvec
|
||||||
|
.into_iter()
|
||||||
|
.map(|(x, y)| (x, if y.is_empty() { None } else { Some(y) }))
|
||||||
|
.collect::<HashMap<String, Option<String>>>();
|
||||||
|
|
||||||
|
println!("Starting category");
|
||||||
|
for category in PkgCategory::iter() {
|
||||||
|
desktoppicks.shuffle(&mut rng);
|
||||||
|
let mut cvec = vec![];
|
||||||
|
let mut allvec = vec![];
|
||||||
|
let mut rpkgs = recpkgs.clone();
|
||||||
|
fn checkpkgs(
|
||||||
|
pkg: String,
|
||||||
|
pospkgs: &HashMap<String, Option<String>>,
|
||||||
|
appdata: &HashMap<String, AppData>,
|
||||||
|
category: PkgCategory,
|
||||||
|
) -> bool {
|
||||||
|
match category {
|
||||||
|
PkgCategory::Audio => {
|
||||||
|
// Audio:
|
||||||
|
// - pkgs/applications/audio
|
||||||
|
if let Some(Some(pos)) = pospkgs.get(&pkg) {
|
||||||
|
if pos.starts_with("pkgs/applications/audio") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(data) = appdata.get(&pkg) {
|
||||||
|
if let Some(categories) = &data.categories {
|
||||||
|
if categories.contains(&String::from("Audio")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(data) = &p.appdata {
|
|
||||||
if let Some(categories) = &data.categories {
|
|
||||||
if categories.contains(&String::from("Audio")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
PkgCategory::Development => {
|
false
|
||||||
// Development:
|
}
|
||||||
// - pkgs/development
|
PkgCategory::Development => {
|
||||||
// - pkgs/applications/terminal-emulators
|
// Development:
|
||||||
// - xdg: Development
|
// - pkgs/development
|
||||||
if let Some(p) = pkgs.get(&pkg) {
|
// - pkgs/applications/terminal-emulators
|
||||||
if let Some(pos) = &p.meta.position {
|
// - xdg: Development
|
||||||
if pos.starts_with("pkgs/development")
|
if let Some(Some(pos)) = pospkgs.get(&pkg) {
|
||||||
|| pos.starts_with(
|
if pos.starts_with("pkgs/development")
|
||||||
"pkgs/applications/terminal-emulators",
|
|| pos
|
||||||
)
|
.starts_with("pkgs/applications/terminal-emulators")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(data) = appdata.get(&pkg) {
|
||||||
|
if let Some(categories) = &data.categories {
|
||||||
|
if categories.contains(&String::from("Development"))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(data) = &p.appdata {
|
|
||||||
if let Some(categories) = &data.categories {
|
|
||||||
if categories
|
|
||||||
.contains(&String::from("Development"))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
PkgCategory::Games => {
|
false
|
||||||
// Games:
|
}
|
||||||
// - pkgs/games
|
PkgCategory::Games => {
|
||||||
// - pkgs/applications/emulators
|
// Games:
|
||||||
// - pkgs/tools/games
|
// - pkgs/games
|
||||||
// - xdg::Games
|
// - pkgs/applications/emulators
|
||||||
if let Some(p) = pkgs.get(&pkg) {
|
// - pkgs/tools/games
|
||||||
if let Some(pos) = &p.meta.position {
|
// - xdg::Games
|
||||||
if pos.starts_with("pkgs/games")
|
if let Some(Some(pos)) = pospkgs.get(&pkg) {
|
||||||
|| pos.starts_with(
|
if pos.starts_with("pkgs/games")
|
||||||
"pkgs/applications/emulators",
|
|| pos.starts_with("pkgs/applications/emulators")
|
||||||
)
|
|| pos.starts_with("pkgs/tools/games")
|
||||||
|| pos.starts_with("pkgs/tools/games")
|
{
|
||||||
{
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(data) = &appdata.get(&pkg) {
|
||||||
|
if let Some(categories) = &data.categories {
|
||||||
|
if categories.contains(&String::from("Games")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(data) = &p.appdata {
|
|
||||||
if let Some(categories) = &data.categories {
|
|
||||||
if categories.contains(&String::from("Games")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
PkgCategory::Graphics => {
|
false
|
||||||
// Graphics:
|
}
|
||||||
// - pkgs/applications/graphics
|
PkgCategory::Graphics => {
|
||||||
// - xdg: Graphics
|
// Graphics:
|
||||||
if let Some(p) = pkgs.get(&pkg) {
|
// - pkgs/applications/graphics
|
||||||
if let Some(pos) = &p.meta.position {
|
// - xdg: Graphics
|
||||||
if pos.starts_with("pkgs/applications/graphics")
|
if let Some(Some(pos)) = pospkgs.get(&pkg) {
|
||||||
|| pos.starts_with("xdg:Graphics")
|
if pos.starts_with("pkgs/applications/graphics")
|
||||||
{
|
|| pos.starts_with("xdg:Graphics")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(data) = &appdata.get(&pkg) {
|
||||||
|
if let Some(categories) = &data.categories {
|
||||||
|
if categories.contains(&String::from("Graphics")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(data) = &p.appdata {
|
|
||||||
if let Some(categories) = &data.categories {
|
|
||||||
if categories.contains(&String::from("Graphics")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
PkgCategory::Network => {
|
|
||||||
// Network:
|
|
||||||
// - pkgs/applications/networking
|
|
||||||
// - xdg: Network
|
|
||||||
if let Some(p) = pkgs.get(&pkg) {
|
|
||||||
if let Some(pos) = &p.meta.position {
|
|
||||||
if pos.starts_with("pkgs/applications/networking")
|
|
||||||
|| pos.starts_with("xdg:Network")
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(data) = &p.appdata {
|
|
||||||
if let Some(categories) = &data.categories {
|
|
||||||
if categories.contains(&String::from("Network")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
PkgCategory::Video => {
|
|
||||||
// Video:
|
|
||||||
// - pkgs/applications/video
|
|
||||||
// - xdg: Video
|
|
||||||
if let Some(p) = pkgs.get(&pkg) {
|
|
||||||
if let Some(pos) = &p.meta.position {
|
|
||||||
if pos.starts_with("pkgs/applications/video")
|
|
||||||
|| pos.starts_with("xdg:Video")
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(data) = &p.appdata {
|
|
||||||
if let Some(categories) = &data.categories {
|
|
||||||
if categories.contains(&String::from("Video")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
PkgCategory::Network => {
|
||||||
|
// Network:
|
||||||
|
// - pkgs/applications/networking
|
||||||
|
// - xdg: Network
|
||||||
|
if let Some(Some(pos)) = pospkgs.get(&pkg) {
|
||||||
|
if pos.starts_with("pkgs/applications/networking")
|
||||||
|
|| pos.starts_with("xdg:Network")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(data) = &appdata.get(&pkg) {
|
||||||
|
if let Some(categories) = &data.categories {
|
||||||
|
if categories.contains(&String::from("Network")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
PkgCategory::Video => {
|
||||||
|
// Video:
|
||||||
|
// - pkgs/applications/video
|
||||||
|
// - xdg: Video
|
||||||
|
if let Some(Some(pos)) = pospkgs.get(&pkg) {
|
||||||
|
if pos.starts_with("pkgs/applications/video")
|
||||||
|
|| pos.starts_with("xdg:Video")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(data) = &appdata.get(&pkg) {
|
||||||
|
if let Some(categories) = &data.categories {
|
||||||
|
if categories.contains(&String::from("Video")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for pkg in desktoppicks.iter().take(3) {
|
for pkg in desktoppicks.iter().take(3) {
|
||||||
if checkpkgs(pkg.to_string(), &appdatapkgs, category.clone()) {
|
if checkpkgs(pkg.to_string(), &pospkgs, &appdata, category.clone()) {
|
||||||
|
cvec.push(pkg.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while cvec.len() < 12 {
|
||||||
|
if let Some(pkg) = rpkgs.pop() {
|
||||||
|
if !cvec.contains(&pkg.to_string())
|
||||||
|
&& checkpkgs(
|
||||||
|
pkg.to_string(),
|
||||||
|
&pospkgs,
|
||||||
|
&appdata,
|
||||||
|
category.clone(),
|
||||||
|
)
|
||||||
|
{
|
||||||
cvec.push(pkg.to_string());
|
cvec.push(pkg.to_string());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while cvec.len() < 12 {
|
|
||||||
if let Some(pkg) = rpkgs.pop() {
|
|
||||||
if !cvec.contains(&pkg.to_string())
|
|
||||||
&& checkpkgs(
|
|
||||||
pkg.to_string(),
|
|
||||||
&appdatapkgs,
|
|
||||||
category.clone(),
|
|
||||||
)
|
|
||||||
{
|
|
||||||
cvec.push(pkg.to_string());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let catagortypkgs = pkgs
|
|
||||||
.iter()
|
|
||||||
.filter(|(x, _)| {
|
|
||||||
if let Some(p) = appdatapkgs.get(*x) {
|
|
||||||
if let Some(position) = &p.meta.position {
|
|
||||||
(position.starts_with("pkgs/applications/audio") && category == PkgCategory::Audio)
|
|
||||||
|| (position.starts_with("pkgs/applications/terminal-emulators") && category == PkgCategory::Development)
|
|
||||||
|| (position.starts_with("pkgs/applications/emulators") && category == PkgCategory::Games)
|
|
||||||
|| (position.starts_with("pkgs/applications/graphics") && category == PkgCategory::Graphics)
|
|
||||||
|| (position.starts_with("pkgs/applications/networking") && category == PkgCategory::Network)
|
|
||||||
|| (position.starts_with("pkgs/applications/video") && category == PkgCategory::Video)
|
|
||||||
|| (position.starts_with("pkgs/tools/games") && category == PkgCategory::Games)
|
|
||||||
|| (position.starts_with("pkgs/games") && category == PkgCategory::Games)
|
|
||||||
|| (position.starts_with("pkgs/development") && category == PkgCategory::Development)
|
|
||||||
|| appdatapkgs.contains_key(x)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<HashMap<_, _>>();
|
|
||||||
|
|
||||||
for pkg in catagortypkgs.keys() {
|
|
||||||
if checkpkgs(pkg.to_string(), &catagortypkgs, category.clone()) {
|
|
||||||
allvec.push(pkg.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cvec.shuffle(&mut rng);
|
|
||||||
allvec.sort_by_key(|x| x.to_lowercase());
|
|
||||||
catpicks.insert(category.clone(), cvec);
|
|
||||||
catpkgs.insert(category.clone(), allvec);
|
|
||||||
}
|
|
||||||
|
|
||||||
while recpicks.len() < 12 {
|
|
||||||
if let Some(p) = recommendedpkgs.pop() {
|
|
||||||
if !recpicks.contains(&p.to_string()) {
|
|
||||||
recpicks.push(p);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recpicks.shuffle(&mut rng);
|
|
||||||
|
let catagortypkgs = pkglist
|
||||||
|
.iter()
|
||||||
|
.filter(|x| {
|
||||||
|
if appdata.get(*x).is_some() {
|
||||||
|
if let Some(Some(position)) = &pospkgs.get(*x) {
|
||||||
|
(position.starts_with("pkgs/applications/audio")
|
||||||
|
&& category == PkgCategory::Audio)
|
||||||
|
|| (position.starts_with(
|
||||||
|
"pkgs/applications/terminal-emulators",
|
||||||
|
) && category == PkgCategory::Development)
|
||||||
|
|| (position.starts_with("pkgs/applications/emulators")
|
||||||
|
&& category == PkgCategory::Games)
|
||||||
|
|| (position.starts_with("pkgs/applications/graphics")
|
||||||
|
&& category == PkgCategory::Graphics)
|
||||||
|
|| (position
|
||||||
|
.starts_with("pkgs/applications/networking")
|
||||||
|
&& category == PkgCategory::Network)
|
||||||
|
|| (position.starts_with("pkgs/applications/video")
|
||||||
|
&& category == PkgCategory::Video)
|
||||||
|
|| (position.starts_with("pkgs/tools/games")
|
||||||
|
&& category == PkgCategory::Games)
|
||||||
|
|| (position.starts_with("pkgs/games")
|
||||||
|
&& category == PkgCategory::Games)
|
||||||
|
|| (position.starts_with("pkgs/development")
|
||||||
|
&& category == PkgCategory::Development)
|
||||||
|
|| recpkgs.contains(x)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for pkg in catagortypkgs {
|
||||||
|
if checkpkgs(pkg.to_string(), &pospkgs, &appdata, category.clone()) {
|
||||||
|
allvec.push(pkg.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cvec.shuffle(&mut rng);
|
||||||
|
allvec.sort_by_key(|x| x.to_lowercase());
|
||||||
|
catpicks.insert(category.clone(), cvec);
|
||||||
|
catpkgs.insert(category.clone(), allvec);
|
||||||
}
|
}
|
||||||
|
|
||||||
match cr {
|
while recpicks.len() < 12 {
|
||||||
CacheReturn::Init => {
|
if let Some(p) = recpkgs.pop() {
|
||||||
sender.output(AppMsg::Initialize(pkgs, recpicks, newpkgs, catpicks, catpkgs, profilepkgs));
|
if !recpicks.contains(&p.to_string()) {
|
||||||
}
|
recpicks.push(p.to_string());
|
||||||
CacheReturn::Update => {
|
}
|
||||||
sender.output(AppMsg::ReloadUpdateItems(pkgs, newpkgs));
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
recpicks.shuffle(&mut rng);
|
||||||
|
|
||||||
|
sender.output(AppMsg::Initialize(
|
||||||
|
pkgdb, nixpkgsdb, systemdb, appdata, recpicks, catpicks, catpkgs,
|
||||||
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,12 +387,11 @@ pub enum LoadErrorMsg {
|
|||||||
Show(String, String),
|
Show(String, String),
|
||||||
Retry,
|
Retry,
|
||||||
Close,
|
Close,
|
||||||
// Preferences,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
impl SimpleComponent for LoadErrorModel {
|
impl SimpleComponent for LoadErrorModel {
|
||||||
type InitParams = gtk::Window;
|
type Init = gtk::Window;
|
||||||
type Input = LoadErrorMsg;
|
type Input = LoadErrorMsg;
|
||||||
type Output = AppMsg;
|
type Output = AppMsg;
|
||||||
type Widgets = LoadErrorWidgets;
|
type Widgets = LoadErrorWidgets;
|
||||||
@ -472,7 +423,7 @@ impl SimpleComponent for LoadErrorModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
parent_window: Self::InitParams,
|
parent_window: Self::Init,
|
||||||
root: &Self::Root,
|
root: &Self::Root,
|
||||||
sender: ComponentSender<Self>,
|
sender: ComponentSender<Self>,
|
||||||
) -> ComponentParts<Self> {
|
) -> ComponentParts<Self> {
|
||||||
|
Loading…
Reference in New Issue
Block a user