RR: Partial User page!

This commit is contained in:
Ward from fusion-voyager-3 2024-02-04 21:21:11 +03:00
parent cc916d1516
commit 6a8245f0ff
6 changed files with 235 additions and 6 deletions

39
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.79" version = "1.0.79"
@ -427,6 +436,7 @@ dependencies = [
"async-channel", "async-channel",
"gtk4", "gtk4",
"libadwaita", "libadwaita",
"regex",
] ]
[[package]] [[package]]
@ -640,6 +650,35 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "regex"
version = "1.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.0" version = "0.4.0"

View File

@ -9,3 +9,4 @@ edition = "2021"
adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] } adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] }
gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] } gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] }
async-channel = "2.1.1" async-channel = "2.1.1"
regex = "1.10.3"

View File

@ -17,6 +17,7 @@ use crate::connection_check::check_internet_connection;
// carousel crates // carousel crates
use crate::first_setup::initial_carousel::initial_carousel; use crate::first_setup::initial_carousel::initial_carousel;
use crate::first_setup::internet_carousel::internet_carousel; use crate::first_setup::internet_carousel::internet_carousel;
use crate::first_setup::user_carousel::user_carousel;
use crate::first_setup::update_carousel::update_carousel; use crate::first_setup::update_carousel::update_carousel;
pub fn first_setup(window: &adw::ApplicationWindow) { pub fn first_setup(window: &adw::ApplicationWindow) {
@ -63,7 +64,7 @@ pub fn first_setup(window: &adw::ApplicationWindow) {
// Initial Carousel // Initial Carousel
initial_carousel(&first_setup_carousel); initial_carousel(&first_setup_carousel);
internet_carousel(&first_setup_carousel, &internet_connected, &window); internet_carousel(&first_setup_carousel, &internet_connected, &window);
user_carousel(&first_setup_carousel);
update_carousel(&first_setup_carousel, &internet_connected); update_carousel(&first_setup_carousel, &internet_connected);
// Add file to window // Add file to window

View File

@ -89,7 +89,6 @@ pub fn internet_carousel(first_setup_carousel: &adw::Carousel, internet_connecte
.valign(Align::End) .valign(Align::End)
.vexpand(true) .vexpand(true)
.hexpand(true) .hexpand(true)
.hexpand(true)
.margin_end(15) .margin_end(15)
.margin_start(15) .margin_start(15)
.margin_bottom(15) .margin_bottom(15)
@ -165,8 +164,8 @@ pub fn internet_carousel(first_setup_carousel: &adw::Carousel, internet_connecte
first_setup_internet_button.connect_clicked(move |_| { first_setup_internet_button.connect_clicked(move |_| {
let env_xdg_session_desktop = env::var("XDG_SESSION_DESKTOP").unwrap(); let env_xdg_session_desktop = env::var("XDG_SESSION_DESKTOP").unwrap();
if env_xdg_session_desktop.contains("gnome") || env_xdg_session_desktop.contains("ubuntu") { if env_xdg_session_desktop.contains("gnome") || env_xdg_session_desktop.contains("ubuntu") {
Command::new("gtk-launch") Command::new("gnome-control-center")
.arg("gnome-network-panel.desktop") .arg("network")
.spawn() .spawn()
.expect("gnome-control-center failed to start"); .expect("gnome-control-center failed to start");
} else { } else {

View File

@ -1,5 +1,5 @@
pub mod first_setup; pub mod first_setup;
pub mod initial_carousel; pub mod initial_carousel;
pub mod internet_carousel; pub mod internet_carousel;
pub mod user_carousel;
pub mod update_carousel; pub mod update_carousel;

View File

@ -0,0 +1,189 @@
// GTK crates
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::prelude::*;
use gtk::*;
use adw::prelude::*;
use adw::*;
use glib::*;
use gdk::Display;
//use crate::check_internet_connection;
use std::process::Command;
use std::cell::RefCell;
use std::rc::Rc;
use std::borrow::Borrow as the_rc_borrow;
use regex::Regex;
use std::env;
use gtk::Align::Center;
use gtk::gio::ffi::GAsyncReadyCallback;
use gtk::pango::TextTransform::Capitalize;
fn only_alphanumeric(input: &str) -> bool {
return input.chars().all(|c| c.is_alphanumeric());
}
fn uppercase_first_letter(s: &str) -> String {
let mut c = s.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().chain(c).collect(),
}
}
pub fn user_carousel(first_setup_carousel: &adw::Carousel) {
let user_info_username_valid = Rc::new(RefCell::new(false));
let user_info_full_name_valid = Rc::new(RefCell::new(false));
let user_info_passwords_valid = Rc::new(RefCell::new(false));
let first_setup_user_box = gtk::Box::builder()
// that puts items vertically
.orientation(Orientation::Vertical)
.hexpand(true)
.vexpand(true)
.margin_end(15)
.margin_start(15)
.margin_bottom(15)
.margin_top(15)
.build();
let first_setup_user_box_text = adw::StatusPage::builder()
.title("User setup")
.description("Create a user account.")
.hexpand(true)
.valign(Align::Start)
.build();
first_setup_user_box_text.add_css_class("compact");
let user_info_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.valign(Align::Center)
.vexpand(true)
.hexpand(true)
.build();
let user_info_box_clamp = adw::Clamp::builder()
.child(&user_info_box)
.maximum_size(500)
.build();
let user_info_username = adw::EntryRow::builder()
.hexpand(true)
.title("Username:")
.input_purpose(InputPurpose::Alpha)
.input_hints(InputHints::LOWERCASE)
.build();
let user_info_full_name = adw::EntryRow::builder()
.hexpand(true)
.title("Full name:")
.input_purpose(InputPurpose::Name)
.build();
let user_info_password = adw::PasswordEntryRow::builder()
.hexpand(true)
.title("User password:")
.build();
let user_info_password_verify = adw::PasswordEntryRow::builder()
.hexpand(true)
.title("Enter User password again:")
.visible(false)
.build();
let user_info_avatar = adw::Avatar::builder()
.show_initials(true)
.size(128)
.build();
let _user_info_avatar_full_name_binding = user_info_full_name
.bind_property("text", &user_info_avatar, "text")
.sync_create()
.build();
let user_info_listbox = gtk::ListBox::builder()
.margin_top(15)
.margin_bottom(15)
.margin_start(15)
.margin_end(15)
.build();
user_info_listbox.add_css_class("boxed-list");
let user_next_button = gtk::Button::builder()
.label("Next")
.sensitive(false)
.halign(Align::Center)
.valign(Align::End)
.vexpand(true)
.hexpand(true)
.build();
user_next_button.add_css_class("suggested-action");
user_next_button.add_css_class("pill");
first_setup_carousel.append(&first_setup_user_box);
user_info_listbox.append(&user_info_username);
user_info_listbox.append(&user_info_full_name);
user_info_listbox.append(&user_info_password);
user_info_listbox.append(&user_info_password_verify);
user_info_box.append(&user_info_avatar);
user_info_box.append(&user_info_listbox);
first_setup_user_box.append(&first_setup_user_box_text);
first_setup_user_box.append(&user_info_box_clamp);
first_setup_user_box.append(&user_next_button);
user_info_username.connect_changed(clone!(@strong user_info_username_valid, @weak user_info_username, @weak user_info_full_name => move |_| {
let user_info_username_string = user_info_username.text().to_string();
user_info_full_name.set_text(&uppercase_first_letter(&user_info_username_string));
if user_info_username_string.len() > 32 {
user_info_username.set_text(&user_info_username_string[..32]);
user_info_username.set_position(-1);
}
if Regex::new(r"[A-Z]").unwrap().is_match(&user_info_username_string) {
user_info_username.set_text(&user_info_username_string.to_lowercase());
user_info_username.set_position(-1);
}
if !only_alphanumeric(&user_info_username_string) {
*user_info_username_valid.borrow_mut()=true;
} else {
*user_info_username_valid.borrow_mut()=false;
}
if user_info_username_string != "pikaos" {
*user_info_username_valid.borrow_mut()=true;
} else {
*user_info_username_valid.borrow_mut()=false;
}
if user_info_username_string != "root" {
*user_info_username_valid.borrow_mut()=true;
} else {
*user_info_username_valid.borrow_mut()=false;
}
}));
user_info_full_name.connect_changed(clone!(@strong user_info_full_name_valid, @weak user_info_full_name => move |_| {
let user_info_full_name_string = user_info_full_name.text().to_string();
if user_info_full_name_string.len() > 32 {
user_info_full_name.set_text(&user_info_full_name_string[..32]);
user_info_full_name.set_position(-1);
}
}));
user_next_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(3), true);
}));
}