mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-04-20 19:44:50 +00:00
feat: provide command to install missing dependencies in missing dependencies dialog
This commit is contained in:
parent
24d07b94b2
commit
e53b282210
3 changed files with 162 additions and 49 deletions
|
@ -9,39 +9,56 @@ pub enum LinuxDistro {
|
|||
Debian,
|
||||
Fedora,
|
||||
Gentoo,
|
||||
// TODO: add Nix,
|
||||
Suse,
|
||||
}
|
||||
|
||||
pub fn get_distro() -> Option<LinuxDistro> {
|
||||
if let Some(mut reader) = get_reader("/etc/issue") {
|
||||
let mut buf = String::default();
|
||||
if reader.read_to_string(&mut buf).is_ok() {
|
||||
buf = buf.trim().to_lowercase();
|
||||
if buf.contains("arch linux")
|
||||
|| buf.contains("manjaro")
|
||||
|| buf.contains("steamos")
|
||||
|| buf.contains("steam os")
|
||||
{
|
||||
return Some(LinuxDistro::Arch);
|
||||
}
|
||||
if buf.contains("debian")
|
||||
|| buf.contains("ubuntu")
|
||||
|| buf.contains("mint")
|
||||
|| buf.contains("elementary")
|
||||
|| buf.contains("pop")
|
||||
{
|
||||
return Some(LinuxDistro::Debian);
|
||||
}
|
||||
if buf.contains("fedora") || buf.contains("nobara") {
|
||||
return Some(LinuxDistro::Fedora);
|
||||
}
|
||||
if buf.contains("gentoo") {
|
||||
return Some(LinuxDistro::Gentoo);
|
||||
}
|
||||
if buf.contains("alpine") || buf.contains("postmarket") {
|
||||
return Some(LinuxDistro::Alpine);
|
||||
impl LinuxDistro {
|
||||
pub fn get() -> Option<Self> {
|
||||
if let Some(mut reader) = get_reader("/etc/issue") {
|
||||
let mut buf = String::default();
|
||||
if reader.read_to_string(&mut buf).is_ok() {
|
||||
buf = buf.trim().to_lowercase();
|
||||
if buf.contains("arch linux")
|
||||
|| buf.contains("manjaro")
|
||||
|| buf.contains("steamos")
|
||||
|| buf.contains("steam os")
|
||||
{
|
||||
return Some(Self::Arch);
|
||||
}
|
||||
if buf.contains("debian")
|
||||
|| buf.contains("ubuntu")
|
||||
|| buf.contains("mint")
|
||||
|| buf.contains("elementary")
|
||||
|| buf.contains("pop")
|
||||
{
|
||||
return Some(Self::Debian);
|
||||
}
|
||||
if buf.contains("fedora") || buf.contains("nobara") {
|
||||
return Some(Self::Fedora);
|
||||
}
|
||||
if buf.contains("gentoo") {
|
||||
return Some(Self::Gentoo);
|
||||
}
|
||||
if buf.contains("alpine") || buf.contains("postmarket") {
|
||||
return Some(Self::Alpine);
|
||||
}
|
||||
|
||||
// TODO: detect suse, sles, rhel, nix
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
None
|
||||
pub fn install_command(&self, packages: &[String]) -> String {
|
||||
match self {
|
||||
Self::Arch => format!("sudo pacman -Syu {}", packages.join(" ")),
|
||||
Self::Alpine => format!("sudo apk add {}", packages.join(" ")),
|
||||
Self::Debian => format!("sudo apt install {}", packages.join(" ")),
|
||||
Self::Fedora => format!("sudo dnf install {}", packages.join(" ")),
|
||||
Self::Gentoo => format!("sudo emerge {}", packages.join(" ")),
|
||||
Self::Suse => format!("sudo zypper install {}", packages.join(" ")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use gtk::traits::{GtkApplicationExt, GtkWindowExt};
|
||||
use gtk::{
|
||||
prelude::IsA,
|
||||
traits::{GtkApplicationExt, GtkWindowExt},
|
||||
};
|
||||
use relm4::{adw::traits::MessageDialogExt, prelude::*};
|
||||
|
||||
pub fn alert(title: &str, msg: Option<&str>, parent: Option<>k::Window>) {
|
||||
fn alert_base(title: &str, msg: Option<&str>, parent: Option<>k::Window>) -> adw::MessageDialog {
|
||||
let d = adw::MessageDialog::builder()
|
||||
.modal(true)
|
||||
.heading(title)
|
||||
|
@ -15,5 +18,23 @@ pub fn alert(title: &str, msg: Option<&str>, parent: Option<>k::Window>) {
|
|||
d.set_transient_for(gtk::Application::default().active_window().as_ref());
|
||||
}
|
||||
d.add_response("ok", "_Ok");
|
||||
d
|
||||
}
|
||||
|
||||
pub fn alert(title: &str, msg: Option<&str>, parent: Option<>k::Window>) {
|
||||
let d = alert_base(title, msg, parent);
|
||||
d.present();
|
||||
}
|
||||
|
||||
pub fn alert_w_widget(
|
||||
title: &str,
|
||||
msg: Option<&str>,
|
||||
widget: Option<>k::Widget>,
|
||||
parent: Option<>k::Window>,
|
||||
) {
|
||||
let d = alert_base(title, msg, parent);
|
||||
if let Some(w) = widget {
|
||||
d.set_extra_child(Some(w));
|
||||
}
|
||||
d.present();
|
||||
}
|
||||
|
|
111
src/ui/app.rs
111
src/ui/app.rs
|
@ -1,5 +1,5 @@
|
|||
use super::about_dialog::AboutDialog;
|
||||
use super::alert::alert;
|
||||
use super::alert::{alert, alert_w_widget};
|
||||
use super::build_window::{BuildStatus, BuildWindow};
|
||||
use super::debug_view::{DebugView, DebugViewMsg};
|
||||
use super::fbt_config_editor::{FbtConfigEditor, FbtConfigEditorInit, FbtConfigEditorMsg};
|
||||
|
@ -8,7 +8,7 @@ use super::job_worker::job::WorkerJob;
|
|||
use super::job_worker::JobWorker;
|
||||
use super::libsurvive_setup_window::LibsurviveSetupWindow;
|
||||
use super::main_view::MainViewMsg;
|
||||
use super::util::open_with_default_handler;
|
||||
use super::util::{copy_text, open_with_default_handler};
|
||||
use super::wivrn_conf_editor::{WivrnConfEditor, WivrnConfEditorInit, WivrnConfEditorMsg};
|
||||
use crate::builders::build_basalt::get_build_basalt_jobs;
|
||||
use crate::builders::build_libsurvive::get_build_libsurvive_jobs;
|
||||
|
@ -34,7 +34,7 @@ use crate::file_builders::openvrpaths_vrpath::{
|
|||
set_current_openvrpaths_to_profile, set_current_openvrpaths_to_steam,
|
||||
};
|
||||
use crate::file_utils::setcap_cap_sys_nice_eip;
|
||||
use crate::linux_distro::get_distro;
|
||||
use crate::linux_distro::LinuxDistro;
|
||||
use crate::log_parser::MonadoLog;
|
||||
use crate::paths::{get_data_dir, get_ipc_file_path};
|
||||
use crate::profile::{Profile, XRServiceType};
|
||||
|
@ -466,26 +466,101 @@ impl SimpleComponent for App {
|
|||
if !missing_deps.is_empty() {
|
||||
missing_deps.sort_unstable();
|
||||
missing_deps.dedup(); // dedup only works if sorted, hence the above
|
||||
let distro = get_distro();
|
||||
alert(
|
||||
"Missing dependencies:",
|
||||
Some(
|
||||
let distro = LinuxDistro::get();
|
||||
let (missing_package_list, install_missing_widget): (
|
||||
String,
|
||||
Option<gtk::Widget>,
|
||||
) = if let Some(d) = distro {
|
||||
(
|
||||
missing_deps
|
||||
.iter()
|
||||
.map(|dep| {
|
||||
if let Some(d) = distro {
|
||||
return dep
|
||||
.packages
|
||||
.get(&d)
|
||||
.unwrap_or_else(|| &dep.name)
|
||||
.clone();
|
||||
}
|
||||
dep.name.clone()
|
||||
dep.packages.get(&d).unwrap_or_else(|| &dep.name).clone()
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
.as_str(),
|
||||
),
|
||||
.join(", "),
|
||||
{
|
||||
let packages = missing_deps
|
||||
.iter()
|
||||
.filter_map(|dep| {
|
||||
dep.packages.get(&d).and_then(|s| Some(s.clone()))
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
if packages.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let cmd = d.install_command(&packages);
|
||||
{
|
||||
let container = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.spacing(6)
|
||||
.build();
|
||||
let btn = gtk::Button::builder()
|
||||
.css_classes(["flat", "circular"])
|
||||
.tooltip_text("Copy")
|
||||
.icon_name("edit-copy-symbolic")
|
||||
.vexpand(false)
|
||||
.hexpand(false)
|
||||
.valign(gtk::Align::Center)
|
||||
.halign(gtk::Align::Center)
|
||||
.build();
|
||||
btn.connect_clicked(
|
||||
clone!(@strong cmd => move |_| copy_text(&cmd)),
|
||||
);
|
||||
container.append(
|
||||
>k::ScrolledWindow::builder()
|
||||
.vscrollbar_policy(gtk::PolicyType::Never)
|
||||
.hscrollbar_policy(gtk::PolicyType::Automatic)
|
||||
.css_classes(["card"])
|
||||
.overflow(gtk::Overflow::Hidden)
|
||||
.child(
|
||||
>k::TextView::builder()
|
||||
.hexpand(true)
|
||||
.vexpand(false)
|
||||
.monospace(true)
|
||||
.editable(false)
|
||||
.left_margin(6)
|
||||
.right_margin(6)
|
||||
.top_margin(6)
|
||||
.bottom_margin(18)
|
||||
.buffer(
|
||||
>k::TextBuffer::builder()
|
||||
.text(&cmd)
|
||||
.enable_undo(false)
|
||||
.build(),
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
.build(),
|
||||
);
|
||||
container.append(&btn);
|
||||
Some(container.upcast())
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
(
|
||||
missing_deps
|
||||
.iter()
|
||||
.map(|dep| dep.name.clone())
|
||||
.collect::<Vec<String>>()
|
||||
.join(", "),
|
||||
None,
|
||||
)
|
||||
};
|
||||
alert_w_widget(
|
||||
"Missing dependencies:",
|
||||
Some(&format!(
|
||||
"{}{}",
|
||||
missing_package_list,
|
||||
if install_missing_widget.is_some() {
|
||||
"\n\nYou can install them with the following command:"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
)),
|
||||
install_missing_widget.as_ref(),
|
||||
Some(&self.app_win.clone().upcast::<gtk::Window>()),
|
||||
);
|
||||
return;
|
||||
|
|
Loading…
Add table
Reference in a new issue