expander rows
This commit is contained in:
parent
fa0e0359cd
commit
669f169a79
@ -8,10 +8,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="df2ca9e1-e07d-43f4-bc68-0a6113fc1fa2" name="Changes" comment="">
|
<list default="true" id="df2ca9e1-e07d-43f4-bc68-0a6113fc1fa2" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/apt_package_row/imp.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/apt_package_row/imp.rs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/apt_package_row/imp.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/apt_package_row/imp.rs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/apt_package_row/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/apt_package_row/mod.rs" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/apt_update_page/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/apt_update_page/mod.rs" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@ -103,6 +100,7 @@
|
|||||||
<workItem from="1719504952240" duration="1363000" />
|
<workItem from="1719504952240" duration="1363000" />
|
||||||
<workItem from="1719510804090" duration="7000" />
|
<workItem from="1719510804090" duration="7000" />
|
||||||
<workItem from="1719609702948" duration="9756000" />
|
<workItem from="1719609702948" duration="9756000" />
|
||||||
|
<workItem from="1719635307639" duration="18000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
42
Cargo.lock
generated
42
Cargo.lock
generated
@ -61,6 +61,17 @@ dependencies = [
|
|||||||
"syn 2.0.68",
|
"syn 2.0.68",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.1.19",
|
||||||
|
"libc",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@ -509,6 +520,15 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getopts"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
@ -767,6 +787,15 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -1033,7 +1062,7 @@ version = "1.16.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi 0.3.9",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1147,6 +1176,7 @@ dependencies = [
|
|||||||
"futures 0.3.30",
|
"futures 0.3.30",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
|
"pretty-bytes",
|
||||||
"rust-apt",
|
"rust-apt",
|
||||||
"rust-i18n",
|
"rust-i18n",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1173,6 +1203,16 @@ version = "0.3.30"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty-bytes"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "009d6edd2c1dbf2e1c0cd48a2f7766e03498d49ada7109a01c6911815c685316"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"getopts",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -24,3 +24,4 @@ serde = { version = "1.0.203", features = ["derive"] }
|
|||||||
serde_json = "1.0.118"
|
serde_json = "1.0.118"
|
||||||
async-trait = "0.1.80"
|
async-trait = "0.1.80"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
|
pretty-bytes = "0.2.2"
|
||||||
|
@ -6,6 +6,7 @@ use glib::{subclass::Signal, Properties, clone};
|
|||||||
use gtk::{*};
|
use gtk::{*};
|
||||||
use gtk::Orientation::Horizontal;
|
use gtk::Orientation::Horizontal;
|
||||||
use crate::apt_update_page::AptPackageSocket;
|
use crate::apt_update_page::AptPackageSocket;
|
||||||
|
use pretty_bytes::converter::convert;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
// ANCHOR: custom_button
|
// ANCHOR: custom_button
|
||||||
@ -85,7 +86,7 @@ impl ObjectImpl for AptPackageRow {
|
|||||||
//
|
//
|
||||||
create_prefix_content(&prefix_box, &package_name, &package_arch, &package_installed_version, &package_candidate_version);
|
create_prefix_content(&prefix_box, &package_name, &package_arch, &package_installed_version, &package_candidate_version);
|
||||||
//
|
//
|
||||||
create_expandable_content(&expandable_box);
|
create_expandable_content(obj, &expandable_box, package_description, package_source_uri, package_maintainer, package_size, package_installed_size);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
obj.add_prefix(&prefix_box);
|
obj.add_prefix(&prefix_box);
|
||||||
@ -246,7 +247,7 @@ fn create_prefix_content(prefix_box: >k::Box, package_name: &str ,package_arch
|
|||||||
prefix_box.append(&version_box);
|
prefix_box.append(&version_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_expandable_content(expandable_box: >k::Box) {
|
fn create_expandable_content(apt_package_row: &impl IsA<ExpanderRow>, expandable_box: >k::Box, package_description: String, package_source_uri: String, package_maintainer: String, package_size: u64, package_installed_size: u64) {
|
||||||
let expandable_page_selection_box = gtk::Box::builder()
|
let expandable_page_selection_box = gtk::Box::builder()
|
||||||
.orientation(Orientation::Horizontal)
|
.orientation(Orientation::Horizontal)
|
||||||
.hexpand(false)
|
.hexpand(false)
|
||||||
@ -261,13 +262,17 @@ fn create_expandable_content(expandable_box: >k::Box) {
|
|||||||
expandable_page_selection_box.add_css_class("linked");
|
expandable_page_selection_box.add_css_class("linked");
|
||||||
//
|
//
|
||||||
let description_page_button = gtk::ToggleButton::builder()
|
let description_page_button = gtk::ToggleButton::builder()
|
||||||
.label(t!("changelog_page_button_label"))
|
.label(t!("description_page_button_label"))
|
||||||
.active(true)
|
.active(true)
|
||||||
.build();
|
.build();
|
||||||
let extra_info_page_button = gtk::ToggleButton::builder()
|
let extra_info_page_button = gtk::ToggleButton::builder()
|
||||||
.label(t!("extra_info_page_button_label"))
|
.label(t!("extra_info_page_button_label"))
|
||||||
.group(&description_page_button)
|
.group(&description_page_button)
|
||||||
.build();
|
.build();
|
||||||
|
let uris_page_button = gtk::ToggleButton::builder()
|
||||||
|
.label(t!("uris_page_button_label"))
|
||||||
|
.group(&description_page_button)
|
||||||
|
.build();
|
||||||
let changelog_page_button = gtk::ToggleButton::builder()
|
let changelog_page_button = gtk::ToggleButton::builder()
|
||||||
.label(t!("changelog_page_button_label"))
|
.label(t!("changelog_page_button_label"))
|
||||||
// till we find a way to implement
|
// till we find a way to implement
|
||||||
@ -276,24 +281,45 @@ fn create_expandable_content(expandable_box: >k::Box) {
|
|||||||
.build();
|
.build();
|
||||||
expandable_page_selection_box.append(&description_page_button);
|
expandable_page_selection_box.append(&description_page_button);
|
||||||
expandable_page_selection_box.append(&extra_info_page_button);
|
expandable_page_selection_box.append(&extra_info_page_button);
|
||||||
|
expandable_page_selection_box.append(&uris_page_button);
|
||||||
expandable_page_selection_box.append(&changelog_page_button);
|
expandable_page_selection_box.append(&changelog_page_button);
|
||||||
//
|
//
|
||||||
expandable_box.append(&expandable_page_selection_box);
|
expandable_box.append(&expandable_page_selection_box);
|
||||||
//
|
//
|
||||||
let expandable_stack = gtk::Stack::builder()
|
let expandable_bin = adw::Bin::builder()
|
||||||
.hexpand(true)
|
.hexpand(true)
|
||||||
.vexpand(true)
|
.vexpand(true)
|
||||||
.vhomogeneous(true)
|
|
||||||
.hhomogeneous(true)
|
|
||||||
.transition_type(StackTransitionType::SlideLeftRight)
|
|
||||||
.build();
|
.build();
|
||||||
//
|
//
|
||||||
expandable_box.append(&expandable_stack)
|
apt_package_row.connect_expanded_notify(clone!(@strong expandable_bin, @strong expandable_box, @strong apt_package_row, @strong description_page_button => move |apt_package_row| {
|
||||||
|
if apt_package_row.property("expanded") {
|
||||||
|
expandable_bin.set_child(Some(&extra_info_stack_page(&package_maintainer, package_size, package_installed_size)));
|
||||||
|
description_page_button.set_active(true);
|
||||||
|
expandable_box.append(&expandable_bin)
|
||||||
|
} else {
|
||||||
|
expandable_box.remove(&expandable_bin)
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
//expandable_bin.add_named(&extra_info_stack_page(package_maintainer, package_size, package_installed_size), Some("extra_info_page"));
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extra_info_stack_page() {
|
fn extra_info_stack_page(package_maintainer: &str, package_size: u64, package_installed_size: u64) -> gtk::Box {
|
||||||
//create_color_badge(t!(""))
|
let extra_info_badges_content_box = gtk::Box::builder()
|
||||||
//background-accent-bg
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.sensitive(false)
|
||||||
|
.build();
|
||||||
|
let extra_info_badges_size_group = gtk::SizeGroup::new(SizeGroupMode::Both);
|
||||||
|
let extra_info_badges_size_group0 = gtk::SizeGroup::new(SizeGroupMode::Both);
|
||||||
|
let extra_info_badges_size_group1 = gtk::SizeGroup::new(SizeGroupMode::Both);
|
||||||
|
let package_size = package_size as f64;
|
||||||
|
let package_installed_size = package_installed_size as f64;
|
||||||
|
extra_info_badges_content_box.append(&create_color_badge(&t!("extra_info_maintainer").to_string(), package_maintainer, "background-accent-bg", &extra_info_badges_size_group, &extra_info_badges_size_group0, &extra_info_badges_size_group1));
|
||||||
|
extra_info_badges_content_box.append(&create_color_badge(&t!("extra_info_download_size").to_string(), &convert(package_size), "background-accent-bg", &extra_info_badges_size_group, &extra_info_badges_size_group0, &extra_info_badges_size_group1));
|
||||||
|
extra_info_badges_content_box.append(&create_color_badge(&t!("extra_info_installed_size").to_string(), &convert(package_installed_size), "background-accent-bg", &extra_info_badges_size_group, &extra_info_badges_size_group0, &extra_info_badges_size_group1));
|
||||||
|
extra_info_badges_content_box
|
||||||
}
|
}
|
||||||
fn create_color_badge(
|
fn create_color_badge(
|
||||||
label0_text: &str,
|
label0_text: &str,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
use crate::apt_update_page::AptPackageSocket;
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use crate::apt_update_page::AptPackageSocket;
|
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
pub struct AptPackageRow(ObjectSubclass<imp::AptPackageRow>)
|
pub struct AptPackageRow(ObjectSubclass<imp::AptPackageRow>)
|
||||||
@ -29,7 +29,7 @@ impl AptPackageRow {
|
|||||||
|
|
||||||
impl Default for AptPackageRow {
|
impl Default for AptPackageRow {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(AptPackageSocket{
|
Self::new(AptPackageSocket {
|
||||||
name: "name".to_string(),
|
name: "name".to_string(),
|
||||||
arch: "arch".to_string(),
|
arch: "arch".to_string(),
|
||||||
installed_version: "0.0".to_string(),
|
installed_version: "0.0".to_string(),
|
||||||
@ -38,7 +38,7 @@ impl Default for AptPackageRow {
|
|||||||
source_uri: "??".to_string(),
|
source_uri: "??".to_string(),
|
||||||
maintainer: "??".to_string(),
|
maintainer: "??".to_string(),
|
||||||
size: 0,
|
size: 0,
|
||||||
installed_size: 0
|
installed_size: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
|
use pika_unixsocket_tools::*;
|
||||||
use rust_apt::new_cache;
|
use rust_apt::new_cache;
|
||||||
use tokio::net::{UnixStream};
|
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|
||||||
use rust_apt::progress::{AcquireProgress, DynAcquireProgress};
|
use rust_apt::progress::{AcquireProgress, DynAcquireProgress};
|
||||||
use rust_apt::raw::{AcqTextStatus, ItemDesc, PkgAcquire};
|
use rust_apt::raw::{AcqTextStatus, ItemDesc, PkgAcquire};
|
||||||
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
use tokio::net::UnixStream;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use pika_unixsocket_tools::*;
|
|
||||||
|
|
||||||
pub struct AptUpdateProgressSocket<'a> {
|
pub struct AptUpdateProgressSocket<'a> {
|
||||||
pulse_interval: usize,
|
pulse_interval: usize,
|
||||||
@ -22,7 +22,7 @@ impl<'a> AptUpdateProgressSocket<'a> {
|
|||||||
max: 0,
|
max: 0,
|
||||||
progress: 0.0,
|
progress: 0.0,
|
||||||
percent_socket_path: percent_socket_path,
|
percent_socket_path: percent_socket_path,
|
||||||
status_socket_path: status_socket_path
|
status_socket_path: status_socket_path,
|
||||||
};
|
};
|
||||||
progress
|
progress
|
||||||
}
|
}
|
||||||
@ -40,7 +40,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> {
|
|||||||
/// The higher the number, the less frequent pulse updates will be.
|
/// The higher the number, the less frequent pulse updates will be.
|
||||||
///
|
///
|
||||||
/// Pulse Interval set to 0 assumes the apt defaults.
|
/// Pulse Interval set to 0 assumes the apt defaults.
|
||||||
fn pulse_interval(&self) -> usize { self.pulse_interval }
|
fn pulse_interval(&self) -> usize {
|
||||||
|
self.pulse_interval
|
||||||
|
}
|
||||||
|
|
||||||
/// Called when an item is confirmed to be up-to-date.
|
/// Called when an item is confirmed to be up-to-date.
|
||||||
///
|
///
|
||||||
@ -48,7 +50,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> {
|
|||||||
fn hit(&mut self, item: &ItemDesc) {
|
fn hit(&mut self, item: &ItemDesc) {
|
||||||
let message = format!("Up-to-date: {} {}", item.description(), item.short_desc());
|
let message = format!("Up-to-date: {} {}", item.description(), item.short_desc());
|
||||||
println!("{}", message);
|
println!("{}", message);
|
||||||
Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path));
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(send_progress_status(message, self.status_socket_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when an Item has started to download
|
/// Called when an Item has started to download
|
||||||
@ -57,7 +61,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> {
|
|||||||
fn fetch(&mut self, item: &ItemDesc) {
|
fn fetch(&mut self, item: &ItemDesc) {
|
||||||
let message = format!("Fetching: {} {}", item.description(), item.short_desc());
|
let message = format!("Fetching: {} {}", item.description(), item.short_desc());
|
||||||
println!("{}", message);
|
println!("{}", message);
|
||||||
Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path));
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(send_progress_status(message, self.status_socket_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when an item is successfully and completely fetched.
|
/// Called when an item is successfully and completely fetched.
|
||||||
@ -66,7 +72,9 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> {
|
|||||||
fn done(&mut self, item: &ItemDesc) {
|
fn done(&mut self, item: &ItemDesc) {
|
||||||
let message = format!("Downloading: {} {}", item.description(), item.short_desc());
|
let message = format!("Downloading: {} {}", item.description(), item.short_desc());
|
||||||
println!("{}", message);
|
println!("{}", message);
|
||||||
Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path));
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(send_progress_status(message, self.status_socket_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when progress has started.
|
/// Called when progress has started.
|
||||||
@ -87,9 +95,15 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> {
|
|||||||
///
|
///
|
||||||
/// Print out the ErrorText for the Item.
|
/// Print out the ErrorText for the Item.
|
||||||
fn fail(&mut self, item: &ItemDesc) {
|
fn fail(&mut self, item: &ItemDesc) {
|
||||||
let message = format!("Download Failed!: {} {}", item.description(), item.short_desc());
|
let message = format!(
|
||||||
|
"Download Failed!: {} {}",
|
||||||
|
item.description(),
|
||||||
|
item.short_desc()
|
||||||
|
);
|
||||||
eprintln!("{}", message);
|
eprintln!("{}", message);
|
||||||
Runtime::new().unwrap().block_on(send_progress_status(message, self.status_socket_path));
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(send_progress_status(message, self.status_socket_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called periodically to provide the overall progress information
|
/// Called periodically to provide the overall progress information
|
||||||
@ -98,8 +112,12 @@ impl<'a> DynAcquireProgress for AptUpdateProgressSocket<'a> {
|
|||||||
/// Each line has an overall percent meter and a per active item status
|
/// Each line has an overall percent meter and a per active item status
|
||||||
/// meter along with an overall bandwidth and ETA indicator.
|
/// meter along with an overall bandwidth and ETA indicator.
|
||||||
fn pulse(&mut self, status: &AcqTextStatus, owner: &PkgAcquire) {
|
fn pulse(&mut self, status: &AcqTextStatus, owner: &PkgAcquire) {
|
||||||
let progress_percent: f32 = (status.current_bytes() as f32 * 100.0) / status.total_bytes() as f32;
|
let progress_percent: f32 =
|
||||||
Runtime::new().unwrap().block_on(send_progress_percent(progress_percent, self.percent_socket_path));
|
(status.current_bytes() as f32 * 100.0) / status.total_bytes() as f32;
|
||||||
|
Runtime::new().unwrap().block_on(send_progress_percent(
|
||||||
|
progress_percent,
|
||||||
|
self.percent_socket_path,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,14 +125,25 @@ fn main() {
|
|||||||
let update_cache = new_cache!().unwrap();
|
let update_cache = new_cache!().unwrap();
|
||||||
let percent_socket_path = "/tmp/pika_apt_update_percent.sock";
|
let percent_socket_path = "/tmp/pika_apt_update_percent.sock";
|
||||||
let status_socket_path = "/tmp/pika_apt_update_status.sock";
|
let status_socket_path = "/tmp/pika_apt_update_status.sock";
|
||||||
match update_cache.update(&mut AcquireProgress::new(AptUpdateProgressSocket::new(percent_socket_path, status_socket_path))) {
|
match update_cache.update(&mut AcquireProgress::new(AptUpdateProgressSocket::new(
|
||||||
|
percent_socket_path,
|
||||||
|
status_socket_path,
|
||||||
|
))) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
Runtime::new().unwrap().block_on(send_successful_to_socket(percent_socket_path));
|
Runtime::new()
|
||||||
Runtime::new().unwrap().block_on(send_successful_to_socket(status_socket_path));
|
.unwrap()
|
||||||
|
.block_on(send_successful_to_socket(percent_socket_path));
|
||||||
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(send_successful_to_socket(status_socket_path));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
Runtime::new().unwrap().block_on(send_failed_to_socket(percent_socket_path));
|
Runtime::new()
|
||||||
Runtime::new().unwrap().block_on(send_failed_to_socket(status_socket_path));
|
.unwrap()
|
||||||
|
.block_on(send_failed_to_socket(percent_socket_path));
|
||||||
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(send_failed_to_socket(status_socket_path));
|
||||||
panic!("{}", e.to_string())
|
panic!("{}", e.to_string())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -122,17 +151,27 @@ fn main() {
|
|||||||
|
|
||||||
async fn send_progress_percent(progress_f32: f32, socket_path: &str) {
|
async fn send_progress_percent(progress_f32: f32, socket_path: &str) {
|
||||||
// Connect to the Unix socket
|
// Connect to the Unix socket
|
||||||
let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server");
|
let mut stream = UnixStream::connect(socket_path)
|
||||||
|
.await
|
||||||
|
.expect("Could not connect to server");
|
||||||
|
|
||||||
let message = progress_f32.to_string();
|
let message = progress_f32.to_string();
|
||||||
// Send the message to the server
|
// Send the message to the server
|
||||||
stream.write_all(message.as_bytes()).await.expect("Failed to write to stream");
|
stream
|
||||||
|
.write_all(message.as_bytes())
|
||||||
|
.await
|
||||||
|
.expect("Failed to write to stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_progress_status(message: String, socket_path: &str) {
|
async fn send_progress_status(message: String, socket_path: &str) {
|
||||||
// Connect to the Unix socket
|
// Connect to the Unix socket
|
||||||
let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server");
|
let mut stream = UnixStream::connect(socket_path)
|
||||||
|
.await
|
||||||
|
.expect("Could not connect to server");
|
||||||
|
|
||||||
// Send the message to the server
|
// Send the message to the server
|
||||||
stream.write_all(message.as_bytes()).await.expect("Failed to write to stream");
|
stream
|
||||||
|
.write_all(message.as_bytes())
|
||||||
|
.await
|
||||||
|
.expect("Failed to write to stream");
|
||||||
}
|
}
|
@ -1,19 +1,22 @@
|
|||||||
use std::{fs, thread};
|
use crate::apt_package_row::AptPackageRow;
|
||||||
use std::path::Path;
|
use adw::prelude::*;
|
||||||
use rust_apt::*;
|
use gtk::glib::*;
|
||||||
|
use gtk::*;
|
||||||
|
use pika_unixsocket_tools::*;
|
||||||
use rust_apt::cache::*;
|
use rust_apt::cache::*;
|
||||||
use rust_apt::new_cache;
|
use rust_apt::new_cache;
|
||||||
use rust_apt::records::RecordField;
|
use rust_apt::records::RecordField;
|
||||||
|
use rust_apt::*;
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use gtk::glib::*;
|
use std::sync::atomic::AtomicBool;
|
||||||
use adw::prelude::*;
|
use std::sync::Arc;
|
||||||
use gtk::*;
|
use std::{fs, thread};
|
||||||
use tokio::net::{UnixListener, UnixStream};
|
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
|
use tokio::net::{UnixListener, UnixStream};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use pika_unixsocket_tools::*;
|
|
||||||
use crate::apt_package_row::AptPackageRow;
|
|
||||||
|
|
||||||
pub struct AptPackageSocket {
|
pub struct AptPackageSocket {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -24,7 +27,7 @@ pub struct AptPackageSocket {
|
|||||||
pub source_uri: String,
|
pub source_uri: String,
|
||||||
pub maintainer: String,
|
pub maintainer: String,
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
pub installed_size: u64
|
pub installed_size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
||||||
@ -36,11 +39,15 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
let get_upgradable_sender = get_upgradable_sender.clone();
|
let get_upgradable_sender = get_upgradable_sender.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
Runtime::new().unwrap().block_on(update_percent_socket_server(update_percent_sender));
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(update_percent_socket_server(update_percent_sender));
|
||||||
});
|
});
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
Runtime::new().unwrap().block_on(update_status_socket_server(update_status_sender));
|
Runtime::new()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(update_status_socket_server(update_status_sender));
|
||||||
});
|
});
|
||||||
|
|
||||||
Command::new("pkexec")
|
Command::new("pkexec")
|
||||||
@ -68,6 +75,7 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
.margin_start(15)
|
.margin_start(15)
|
||||||
.margin_end(15)
|
.margin_end(15)
|
||||||
.margin_start(15)
|
.margin_start(15)
|
||||||
|
.sensitive(false)
|
||||||
.build();
|
.build();
|
||||||
packages_boxedlist.add_css_class("boxed-list");
|
packages_boxedlist.add_css_class("boxed-list");
|
||||||
let rows_size_group = gtk::SizeGroup::new(SizeGroupMode::Both);
|
let rows_size_group = gtk::SizeGroup::new(SizeGroupMode::Both);
|
||||||
@ -113,17 +121,21 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
.width_request(500)
|
.width_request(500)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let mut updates_parsed = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
|
let update_parsed_clone0 = Arc::clone(&updates_parsed);
|
||||||
|
|
||||||
let update_percent_server_context = MainContext::default();
|
let update_percent_server_context = MainContext::default();
|
||||||
// The main loop executes the asynchronous block
|
// The main loop executes the asynchronous block
|
||||||
update_percent_server_context.spawn_local(clone!(@weak apt_update_dialog_progress_bar, @weak apt_update_dialog, @strong get_upgradable_sender => async move {
|
update_percent_server_context.spawn_local(clone!(@weak apt_update_dialog_progress_bar, @weak apt_update_dialog, @strong get_upgradable_sender, @strong update_parsed_clone0 => async move {
|
||||||
while let Ok(state) = update_percent_receiver.recv().await {
|
while let Ok(state) = update_percent_receiver.recv().await {
|
||||||
match state.as_ref() {
|
match state.as_ref() {
|
||||||
"FN_OVERRIDE_SUCCESSFUL" => {
|
"FN_OVERRIDE_SUCCESSFUL" => {
|
||||||
let get_upgradable_sender = get_upgradable_sender.clone();
|
let get_upgradable_sender = get_upgradable_sender.clone();
|
||||||
thread::spawn( move || {
|
let update_parsed_clone = Arc::clone(&update_parsed_clone0);
|
||||||
|
thread::spawn(move || {
|
||||||
// Create upgradable list cache
|
// Create upgradable list cache
|
||||||
let upgradable_cache = new_cache!().unwrap();
|
let upgradable_cache = new_cache!().unwrap();
|
||||||
|
|
||||||
// Create pack sort from upgradable_cache
|
// Create pack sort from upgradable_cache
|
||||||
let upgradable_sort = PackageSort::default().upgradable().names();
|
let upgradable_sort = PackageSort::default().upgradable().names();
|
||||||
|
|
||||||
@ -148,6 +160,7 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
};
|
};
|
||||||
get_upgradable_sender.send_blocking(package_struct).unwrap()
|
get_upgradable_sender.send_blocking(package_struct).unwrap()
|
||||||
}
|
}
|
||||||
|
update_parsed_clone.store(true, std::sync::atomic::Ordering::Relaxed)
|
||||||
});
|
});
|
||||||
apt_update_dialog.close();
|
apt_update_dialog.close();
|
||||||
}
|
}
|
||||||
@ -160,7 +173,8 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
|
|
||||||
let update_status_server_context = MainContext::default();
|
let update_status_server_context = MainContext::default();
|
||||||
// The main loop executes the asynchronous block
|
// The main loop executes the asynchronous block
|
||||||
update_status_server_context.spawn_local(clone!(@weak apt_update_dialog, @weak apt_update_dialog_spinner => async move {
|
update_status_server_context.spawn_local(
|
||||||
|
clone!(@weak apt_update_dialog, @weak apt_update_dialog_spinner => async move {
|
||||||
while let Ok(state) = update_status_receiver.recv().await {
|
while let Ok(state) = update_status_receiver.recv().await {
|
||||||
match state.as_ref() {
|
match state.as_ref() {
|
||||||
"FN_OVERRIDE_SUCCESSFUL" => {}
|
"FN_OVERRIDE_SUCCESSFUL" => {}
|
||||||
@ -171,11 +185,14 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
_ => apt_update_dialog.set_body(&state)
|
_ => apt_update_dialog.set_body(&state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let update_parsed_clone1 = Arc::clone(&updates_parsed);
|
||||||
let get_upgradable_server_context = MainContext::default();
|
let get_upgradable_server_context = MainContext::default();
|
||||||
// The main loop executes the asynchronous block
|
// The main loop executes the asynchronous block
|
||||||
get_upgradable_server_context.spawn_local(clone!(@weak packages_boxedlist => async move {
|
get_upgradable_server_context.spawn_local(
|
||||||
|
clone!(@weak packages_boxedlist, @strong update_parsed_clone1 => async move {
|
||||||
while let Ok(state) = get_upgradable_receiver.recv().await {
|
while let Ok(state) = get_upgradable_receiver.recv().await {
|
||||||
packages_boxedlist.append(&AptPackageRow::new(AptPackageSocket {
|
packages_boxedlist.append(&AptPackageRow::new(AptPackageSocket {
|
||||||
name: state.name,
|
name: state.name,
|
||||||
@ -188,9 +205,12 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
size: state.size,
|
size: state.size,
|
||||||
installed_size: state.installed_size
|
installed_size: state.installed_size
|
||||||
}));
|
}));
|
||||||
|
if update_parsed_clone1.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
packages_boxedlist.set_sensitive(true)
|
||||||
}
|
}
|
||||||
}));
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
main_box.append(&searchbar);
|
main_box.append(&searchbar);
|
||||||
main_box.append(&packages_viewport);
|
main_box.append(&packages_viewport);
|
||||||
@ -199,7 +219,6 @@ pub fn apt_update_page(window: adw::ApplicationWindow) -> gtk::Box {
|
|||||||
main_box
|
main_box
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn update_percent_socket_server(buffer_sender: async_channel::Sender<String>) {
|
async fn update_percent_socket_server(buffer_sender: async_channel::Sender<String>) {
|
||||||
// Path to the Unix socket file
|
// Path to the Unix socket file
|
||||||
let socket_path = "/tmp/pika_apt_update_percent.sock";
|
let socket_path = "/tmp/pika_apt_update_percent.sock";
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use adw::prelude::*;
|
|
||||||
use adw::*;
|
|
||||||
use gtk::{Orientation, License};
|
|
||||||
use crate::apt_update_page;
|
use crate::apt_update_page;
|
||||||
use crate::apt_update_page::apt_update_page;
|
use crate::apt_update_page::apt_update_page;
|
||||||
use crate::config::{APP_ICON, APP_ID, APP_GITHUB, VERSION};
|
use crate::config::{APP_GITHUB, APP_ICON, APP_ID, VERSION};
|
||||||
|
use adw::prelude::*;
|
||||||
|
use adw::*;
|
||||||
use gtk::glib::{clone, MainContext};
|
use gtk::glib::{clone, MainContext};
|
||||||
use std::thread;
|
use gtk::{License, Orientation};
|
||||||
use std::process::Command;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::process::Command;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
pub fn build_ui(app: &adw::Application) {
|
pub fn build_ui(app: &adw::Application) {
|
||||||
// setup glib
|
// setup glib
|
||||||
|
23
src/main.rs
23
src/main.rs
@ -1,17 +1,16 @@
|
|||||||
|
|
||||||
mod config;
|
|
||||||
mod build_ui;
|
|
||||||
mod apt_update_page;
|
|
||||||
mod apt_package_row;
|
mod apt_package_row;
|
||||||
|
mod apt_update_page;
|
||||||
|
mod build_ui;
|
||||||
|
mod config;
|
||||||
|
|
||||||
use std::env;
|
use crate::config::APP_ID;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::*;
|
use adw::*;
|
||||||
|
use build_ui::build_ui;
|
||||||
use gdk::Display;
|
use gdk::Display;
|
||||||
use gtk::*;
|
use gtk::*;
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use build_ui::build_ui;
|
use std::env;
|
||||||
use crate::config::{APP_ID};
|
|
||||||
|
|
||||||
// Init translations for current crate.
|
// Init translations for current crate.
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -21,16 +20,16 @@ i18n!("locales", fallback = "en_US");
|
|||||||
/// main function
|
/// main function
|
||||||
fn main() {
|
fn main() {
|
||||||
let current_locale = match env::var_os("LANG") {
|
let current_locale = match env::var_os("LANG") {
|
||||||
Some(v) => v.into_string().unwrap().chars()
|
Some(v) => v
|
||||||
|
.into_string()
|
||||||
|
.unwrap()
|
||||||
|
.chars()
|
||||||
.take_while(|&ch| ch != '.')
|
.take_while(|&ch| ch != '.')
|
||||||
.collect::<String>(),
|
.collect::<String>(),
|
||||||
None => panic!("$LANG is not set"),
|
None => panic!("$LANG is not set"),
|
||||||
};
|
};
|
||||||
rust_i18n::set_locale(¤t_locale);
|
rust_i18n::set_locale(¤t_locale);
|
||||||
let application = adw::Application::new(
|
let application = adw::Application::new(Some(APP_ID), Default::default());
|
||||||
Some(APP_ID),
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
application.connect_startup(|app| {
|
application.connect_startup(|app| {
|
||||||
// The CSS "magic" happens here.
|
// The CSS "magic" happens here.
|
||||||
let provider = CssProvider::new();
|
let provider = CssProvider::new();
|
||||||
|
@ -1,24 +1,34 @@
|
|||||||
use tokio::net::{UnixStream};
|
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
use tokio::net::UnixStream;
|
||||||
|
|
||||||
pub async fn send_successful_to_socket(socket_path: &str) {
|
pub async fn send_successful_to_socket(socket_path: &str) {
|
||||||
// Connect to the Unix socket
|
// Connect to the Unix socket
|
||||||
let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server");
|
let mut stream = UnixStream::connect(socket_path)
|
||||||
|
.await
|
||||||
|
.expect("Could not connect to server");
|
||||||
|
|
||||||
let message = "FN_OVERRIDE_SUCCESSFUL";
|
let message = "FN_OVERRIDE_SUCCESSFUL";
|
||||||
|
|
||||||
// Send the message to the server
|
// Send the message to the server
|
||||||
stream.write_all(message.as_bytes()).await.expect("Failed to write to stream");
|
stream
|
||||||
|
.write_all(message.as_bytes())
|
||||||
|
.await
|
||||||
|
.expect("Failed to write to stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_failed_to_socket(socket_path: &str) {
|
pub async fn send_failed_to_socket(socket_path: &str) {
|
||||||
// Connect to the Unix socket
|
// Connect to the Unix socket
|
||||||
let mut stream = UnixStream::connect(socket_path).await.expect("Could not connect to server");
|
let mut stream = UnixStream::connect(socket_path)
|
||||||
|
.await
|
||||||
|
.expect("Could not connect to server");
|
||||||
|
|
||||||
let message = "FN_OVERRIDE_FAILED";
|
let message = "FN_OVERRIDE_FAILED";
|
||||||
|
|
||||||
// Send the message to the server
|
// Send the message to the server
|
||||||
stream.write_all(message.as_bytes()).await.expect("Failed to write to stream");
|
stream
|
||||||
|
.write_all(message.as_bytes())
|
||||||
|
.await
|
||||||
|
.expect("Failed to write to stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to handle a single client connection
|
// Function to handle a single client connection
|
||||||
@ -30,7 +40,9 @@ pub async fn handle_client(mut stream: UnixStream, buffer_sender: async_channel:
|
|||||||
match stream.read(&mut buffer).await {
|
match stream.read(&mut buffer).await {
|
||||||
Ok(size) => {
|
Ok(size) => {
|
||||||
// Print the received message
|
// Print the received message
|
||||||
buffer_sender.send_blocking(String::from_utf8_lossy(&buffer[..size]).to_string()).expect("Buffer channel closed")
|
buffer_sender
|
||||||
|
.send_blocking(String::from_utf8_lossy(&buffer[..size]).to_string())
|
||||||
|
.expect("Buffer channel closed")
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Print error message if reading fails
|
// Print error message if reading fails
|
||||||
|
Loading…
Reference in New Issue
Block a user