Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions po/en-US/taidan.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ prev = Previous
next = Next
# btn (skip anything)
skip = Skip
steps-devicename = Setting Device Name…
steps-dnfdownloadupdate = Downloading System Update…
steps-dnfinstallupdate = Installing System Update…
steps-script = Running Scriptlet…
Expand Down Expand Up @@ -55,6 +56,12 @@ page-keyboard = Keyboard Layout
page-keyboard-search-layout = Search keyboard layouts…
page-keyboard-search-variant = Search keyboard variants…

## [Device Name]
page-devicename = Name This Device
page-devicename-devicename = Name
page-devicename-hostname = Hostname
page-devicename-error = Hostname must start with a letter, and may only contain lowercase letters, numbers, underscores (<tt>_</tt>), or hyphens (<tt>-</tt>).

## [Username]

# page title
Expand Down
2 changes: 0 additions & 2 deletions scripts/oobe.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,3 @@ if grep -E '^video:' /etc/group; then
# $1 is path to json file for `settings`
usermod -aG video `jq -r '.username' $1`
fi

hostnamectl hostname ultramarine
3 changes: 3 additions & 0 deletions src/backend/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pub struct Settings {
pub kb_layout: String,
pub kb_variant: Option<String>,

pub device_name: String,
pub hostname: String,

pub fullname: String,
pub username: String,

Expand Down
1 change: 1 addition & 0 deletions src/backend/steps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ impl From<Stage> for String {
Stage::DnfDownloadApps(_) => t!("steps-dnfdownloadapps"),
Stage::DnfInstallApps(_) => t!("steps-dnfinstallapps"),
Stage::DriversCodecs(_) => t!("steps-driverscodecs"),
Stage::SetupImf(_) => t!("page-installing-loading"),
_ => t!("page-installing-loading"),
}
}
Expand Down
32 changes: 17 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,22 @@ generate_pages!(Page AppModel AppMsg:
00: Language,
01: Welcome,
02: Keyboard,
03: WhoAreYou,
04: Password,
05: Internet,
06: Analytics,
07: CrashReport,
08: Tweaks,
09: Codecs,
10: InputMethod,
11: NightLight,
12: Theme,
13: Browser,
14: Categories,
15: Installing,
16: Finish,
17: Error,
03: DeviceName,
04: WhoAreYou,
05: Password,
06: Internet,
07: Analytics,
08: CrashReport,
09: Tweaks,
10: Codecs,
11: InputMethod,
12: NightLight,
13: Theme,
14: Browser,
15: Categories,
16: Installing,
17: Finish,
18: Error,
);

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -111,6 +112,7 @@ impl SimpleComponent for AppModel {
Page::Language => *model.language_page.widget(),
Page::Welcome => *model.welcome_page.widget(),
Page::Keyboard => *model.keyboard_page.widget(),
Page::DeviceName => *model.device_name_page.widget(),
Page::WhoAreYou => *model.who_are_you_page.widget(),
Page::Password => *model.password_page.widget(),
Page::Internet => *model.internet_page.widget(),
Expand Down
172 changes: 172 additions & 0 deletions src/pages/_03_devicename.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use regex::Regex;
use tokio::task;

use crate::backend::steps;
use crate::prelude::*;

fn valid_entry(s: &str) -> bool {
let re = Regex::new(r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$").unwrap();
re.is_match(s)
}

#[allow(irrefutable_let_patterns)]
fn autoset_hostname(en: &gtk::Entry, hostname: &str) {
if hostname.is_empty() {
return;
}
let user;
if let first = hostname
.split_once(|c: char| c.is_whitespace())
.map_or(hostname, |(a, _)| a)
&& first.chars().all(|c: char| c.is_ascii_alphanumeric())
&& first.chars().next().unwrap().is_ascii_alphabetic()
{
user = first.to_ascii_lowercase();
} else if let last = hostname
.rsplit_once(|c: char| c.is_whitespace())
.map_or(hostname, |(_, b)| b)
&& last.chars().all(|c: char| c.is_ascii_alphanumeric())
&& last.chars().next().unwrap().is_ascii_alphabetic()
{
user = last.to_ascii_lowercase();
} else {
return;
}
en.set_text(&user);
}

generate_page!(DeviceName {
hostname_field_modified: bool,
hostname_field_controlled: bool,
hostname: gtk::Entry,
error: gtk::Label,
next: libhelium::Button,
}:
init[error hostname](root, sender, model, widgets) {
model.next = widgets.prev_next_btns.next.clone();
}

update(self, message, sender) {
NotifyDeviceName(name: String) => {
if !self.hostname_field_modified {
self.hostname_field_controlled = true;
autoset_hostname(&self.hostname, &name);
}
let mut settings = SETTINGS.write();
settings.device_name = if name.is_empty() {
settings.hostname.clone()
} else {
name
}
},
NotifyHostname(name: String) => {
if self.hostname_field_controlled {
self.hostname_field_controlled = false;
} else {
self.hostname_field_modified = true;
}
let mut settings = SETTINGS.write();
settings.hostname = name.clone();
if settings.device_name.is_empty() {
settings.device_name = name.clone();
}
self.error.set_visible(false);
self.next.set_sensitive(true);
},
InvalidHostname => {
self.error.set_visible(true);
self.next.set_sensitive(false);
},
SetHostname => {
let hostname = SETTINGS.read().hostname.clone();
let device_name = SETTINGS.read().device_name.clone();
let sender = sender.clone();
task::spawn(async move {
if let Err(e) = set_hostname(&hostname, &device_name).await {
tracing::error!(?e, "failed to set hostname");
}
sender.input(DeviceNamePageMsg::Nav(NavAction::Next));
});
}
} => {
}

gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 16,
set_margin_horizontal: 80,
set_vexpand: true,
set_hexpand: true,
set_valign: gtk::Align::Center,
set_halign: gtk::Align::Fill,

gtk::Image {
set_icon_name: Some("computer-symbolic"),
inline_css: "-gtk-icon-size: 64px",
},

gtk::Label {
#[watch]
set_label: &t!("page-devicename"),
add_css_class: "view-subtitle",
inline_css: "font-weight: bold",
},

gtk::Entry {
set_hexpand: true,
set_halign: gtk::Align::Fill,
#[watch]
set_placeholder_text: Some(&t!("page-devicename-devicename")),
connect_changed[sender] => move |e| sender.input(Self::Input::NotifyDeviceName(e.text().to_string())),
},

#[local_ref] hostname ->
gtk::Entry {
set_hexpand: true,
set_halign: gtk::Align::Fill,
#[watch]
set_placeholder_text: Some(&t!("page-devicename-hostname")),
connect_changed[sender] => move |e| if valid_entry(e.text().as_str()) {
sender.input(Self::Input::NotifyHostname(e.text().to_string()))
} else {
sender.input(Self::Input::InvalidHostname)
},
connect_activate[sender] => move |e| if valid_entry(e.text().as_str()) { sender.input(Self::Input::SetHostname) },
},

#[local_ref] error ->
gtk::Label {
#[watch]
set_label: &t!("page-devicename-error"),
set_use_markup: true,
set_visible: false,
add_css_class: "error",
},
},

#[name(prev_next_btns)]
#[template] crate::ui::PrevNextBtns {
#[template_child] prev {
#[watch]
set_label: &t!("prev"),
connect_clicked => Self::Input::Nav(NavAction::Back),
},
#[template_child] next {
#[watch]
set_label: &t!("next"),
set_sensitive: false,
connect_clicked => Self::Input::SetHostname,
}
}
);

#[tracing::instrument]
async fn set_hostname(hostname: &str, device_name: &str) -> color_eyre::Result<()> {
if cfg!(debug_assertions) {
tracing::debug!("skipping set_hostname since debug_assertions is on");
return Ok(());
}
steps::acmd("hostnamectl", &["set-hostname", device_name, "--pretty"]).await?;
steps::acmd("hostnamectl", &["set-hostname", hostname, "--static"]).await?;
Ok(())
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/pages/_10_inputmethod.rs → src/pages/_11_inputmethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ kurage::generate_component!(MoreBox {
key_controller_lang.connect_key_pressed(move |_, key, _, _| {
if key == gtk::gdk::Key::Return {
// Navigate to next page when Enter is pressed
sender_clone.output(NavAction::Next);
sender_clone.output(NavAction::Next).expect("cannot output Next");
gtk::glib::Propagation::Stop
} else {
gtk::glib::Propagation::Proceed
Expand All @@ -63,7 +63,7 @@ kurage::generate_component!(MoreBox {
key_controller_im.connect_key_pressed(move |_, key, _, _| {
if key == gtk::gdk::Key::Return {
// Navigate to next page when Enter is pressed
sender_clone.output(NavAction::Next);
sender_clone.output(NavAction::Next).expect("cannot output Next");
gtk::glib::Propagation::Stop
} else {
gtk::glib::Propagation::Proceed
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
37 changes: 19 additions & 18 deletions src/pages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@
pub mod _00_language;
pub mod _01_welcome;
pub mod _02_keyboard;
pub mod _03_whoareyou;
pub mod _04_password;
pub mod _05_internet;
pub mod _06_analytics;
pub mod _07_crashreport;
pub mod _08_tweaks;
pub mod _09_codecs;
pub mod _10_inputmethod;
pub mod _11_nightlight;
pub mod _12_theme;
pub mod _13_browser;
pub mod _14_categories;
pub mod _15_installing;
pub mod _16_finish;
pub mod _17_error;
pub mod _03_devicename;
pub mod _04_whoareyou;
pub mod _05_password;
pub mod _06_internet;
pub mod _07_analytics;
pub mod _08_crashreport;
pub mod _09_tweaks;
pub mod _10_codecs;
pub mod _11_inputmethod;
pub mod _12_nightlight;
pub mod _13_theme;
pub mod _14_browser;
pub mod _15_categories;
pub mod _16_installing;
pub mod _17_finish;
pub mod _18_error;

pub(crate) use _13_browser::BROWSER_CATEGORY;
pub use _15_installing::InstallingPageMsg;
pub use _17_error::ErrorPageMsg;
pub(crate) use _14_browser::BROWSER_CATEGORY;
pub use _16_installing::InstallingPageMsg;
pub use _18_error::ErrorPageMsg;
Loading