mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-02-02 22:07:13 +08:00
♻ cleanup
This commit is contained in:
parent
1ee447586e
commit
a63d00057c
134
src/tui.cpp
134
src/tui.cpp
@ -24,6 +24,7 @@ namespace fs = std::filesystem;
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
|
||||
#include <range/v3/algorithm/copy.hpp>
|
||||
#include <range/v3/algorithm/search.hpp>
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
#else
|
||||
@ -687,16 +688,9 @@ void install_base() noexcept {
|
||||
|
||||
// Create the base list of packages
|
||||
std::vector<std::string> install_packages{};
|
||||
|
||||
std::unique_ptr<bool[]> kernels_state{new bool[available_kernels.size()]{false}};
|
||||
|
||||
auto kernels{Container::Vertical(detail::from_vector_checklist(available_kernels, kernels_state.get()))};
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
auto content = Renderer(kernels, [&] {
|
||||
return kernels->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
|
||||
});
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
std::string packages{};
|
||||
auto ok_callback = [&] {
|
||||
packages = detail::from_checklist_string(available_kernels, kernels_state.get());
|
||||
@ -717,30 +711,12 @@ void install_base() noexcept {
|
||||
screen.ExitLoopClosure()();
|
||||
};
|
||||
|
||||
ButtonOption button_option{.border = false};
|
||||
auto controls_container = detail::controls_widget({"OK", "Cancel"}, {ok_callback, screen.ExitLoopClosure()}, &button_option);
|
||||
|
||||
auto controls = Renderer(controls_container, [&] {
|
||||
return controls_container->Render() | hcenter | size(HEIGHT, LESS_THAN, 3) | size(WIDTH, GREATER_THAN, 25);
|
||||
});
|
||||
|
||||
static constexpr auto InstStandBseBody = "\nThe base package group will be installed automatically.\nThe base-devel package group is required to use the Arch User Repository (AUR).\n";
|
||||
static constexpr auto UseSpaceBar = "Use [Spacebar] to de/select options listed.";
|
||||
const auto& kernels_options_body = fmt::format("\n{}{}\n", InstStandBseBody, UseSpaceBar);
|
||||
auto global = Container::Vertical({
|
||||
Renderer([&] { return detail::multiline_text(utils::make_multiline(kernels_options_body)); }),
|
||||
Renderer([] { return separator(); }),
|
||||
content,
|
||||
Renderer([] { return separator(); }),
|
||||
controls,
|
||||
});
|
||||
|
||||
auto renderer = Renderer(global, [&] {
|
||||
constexpr auto title = "New CLI Installer | Install Base";
|
||||
return detail::centered_interative_multi(title, global);
|
||||
});
|
||||
|
||||
screen.Loop(renderer);
|
||||
constexpr auto base_title = "New CLI Installer | Install Base";
|
||||
detail::checklist_widget(available_kernels, ok_callback, kernels_state.get(), &screen, kernels_options_body, base_title, {.text_size = nothing});
|
||||
|
||||
/* clang-format off */
|
||||
if (packages.empty()) { return; }
|
||||
@ -788,16 +764,9 @@ void install_desktop() noexcept {
|
||||
|
||||
// Create the base list of packages
|
||||
std::vector<std::string> install_packages{};
|
||||
|
||||
std::unique_ptr<bool[]> des_state{new bool[available_des.size()]{false}};
|
||||
|
||||
auto kernels{Container::Vertical(detail::from_vector_checklist(available_des, des_state.get()))};
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
auto content = Renderer(kernels, [&] {
|
||||
return kernels->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
|
||||
});
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
std::string desktop_env{};
|
||||
auto ok_callback = [&] {
|
||||
desktop_env = detail::from_checklist_string(available_des, des_state.get());
|
||||
@ -805,30 +774,12 @@ void install_desktop() noexcept {
|
||||
screen.ExitLoopClosure()();
|
||||
};
|
||||
|
||||
ButtonOption button_option{.border = false};
|
||||
auto controls_container = detail::controls_widget({"OK", "Cancel"}, {ok_callback, screen.ExitLoopClosure()}, &button_option);
|
||||
|
||||
auto controls = Renderer(controls_container, [&] {
|
||||
return controls_container->Render() | hcenter | size(HEIGHT, LESS_THAN, 3) | size(WIDTH, GREATER_THAN, 25);
|
||||
});
|
||||
|
||||
static constexpr auto InstManDEBody = "\nPlease choose a desktop environment.\n";
|
||||
static constexpr auto UseSpaceBar = "Use [Spacebar] to de/select options listed.";
|
||||
const auto& kernels_options_body = fmt::format("\n{}{}\n", InstManDEBody, UseSpaceBar);
|
||||
auto global = Container::Vertical({
|
||||
Renderer([&] { return detail::multiline_text(utils::make_multiline(kernels_options_body)); }),
|
||||
Renderer([] { return separator(); }),
|
||||
content,
|
||||
Renderer([] { return separator(); }),
|
||||
controls,
|
||||
});
|
||||
const auto& des_options_body = fmt::format("\n{}{}\n", InstManDEBody, UseSpaceBar);
|
||||
|
||||
auto renderer = Renderer(global, [&] {
|
||||
constexpr auto title = "New CLI Installer | Install Desktop";
|
||||
return detail::centered_interative_multi(title, global);
|
||||
});
|
||||
|
||||
screen.Loop(renderer);
|
||||
constexpr auto desktop_title = "New CLI Installer | Install Desktop";
|
||||
detail::checklist_widget(available_des, ok_callback, des_state.get(), &screen, des_options_body, desktop_title, {.text_size = nothing});
|
||||
|
||||
/* clang-format off */
|
||||
if (desktop_env.empty()) { return; }
|
||||
@ -1122,39 +1073,13 @@ void auto_partition() noexcept {
|
||||
|
||||
// Show created partitions
|
||||
const auto& disk_list = utils::exec(fmt::format("lsblk {} -o NAME,TYPE,FSTYPE,SIZE", device_info));
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
/* clang-format off */
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
auto button_back = Button("Back", screen.ExitLoopClosure(), &button_option);
|
||||
|
||||
auto container = Container::Horizontal({button_back});
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return detail::centered_widget(container, "New CLI Installer", detail::multiline_text(utils::make_multiline(disk_list)) | size(HEIGHT, GREATER_THAN, 5));
|
||||
});
|
||||
/* clang-format on */
|
||||
|
||||
screen.Loop(renderer);
|
||||
detail::msgbox_widget(disk_list, size(HEIGHT, GREATER_THAN, 5));
|
||||
}
|
||||
|
||||
// Simple code to show devices / partitions.
|
||||
void show_devices() noexcept {
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
const auto& lsblk = utils::exec("lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep \"disk\\|part\\|lvm\\|crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\\|MOUNTPOINT\"");
|
||||
|
||||
/* clang-format off */
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
auto button_back = Button("Back", screen.ExitLoopClosure(), &button_option);
|
||||
|
||||
auto container = Container::Horizontal({button_back});
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return detail::centered_widget(container, "New CLI Installer", detail::multiline_text(utils::make_multiline(lsblk)) | size(HEIGHT, GREATER_THAN, 5));
|
||||
});
|
||||
/* clang-format on */
|
||||
|
||||
screen.Loop(renderer);
|
||||
detail::msgbox_widget(lsblk, size(HEIGHT, GREATER_THAN, 5));
|
||||
}
|
||||
|
||||
// This function does not assume that the formatted device is the Root installation device as
|
||||
@ -1305,42 +1230,19 @@ void mount_opts() noexcept {
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
auto flags = Container::Vertical(detail::from_vector_checklist(fs_opts, fs_opts_state.get()));
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
auto content = Renderer(flags, [&] {
|
||||
return flags->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
|
||||
});
|
||||
|
||||
auto screen = ScreenInteractive::Fullscreen();
|
||||
auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]);
|
||||
auto ok_callback = [&] {
|
||||
mount_opts_info = detail::from_checklist_string(fs_opts, fs_opts_state.get());
|
||||
screen.ExitLoopClosure()();
|
||||
};
|
||||
|
||||
ButtonOption button_option{.border = false};
|
||||
auto controls_container = detail::controls_widget({"OK", "Cancel"}, {ok_callback, screen.ExitLoopClosure()}, &button_option);
|
||||
const auto& file_sys_formatted = utils::exec(fmt::format("echo {} | sed \"s/.*\\.//g;s/-.*//g\"", file_sys));
|
||||
const auto& fs_title = fmt::format("New CLI Installer | {}", file_sys_formatted);
|
||||
const auto& content_size = size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
|
||||
|
||||
auto controls = Renderer(controls_container, [&] {
|
||||
return controls_container->Render() | hcenter | size(HEIGHT, LESS_THAN, 3) | size(WIDTH, GREATER_THAN, 25);
|
||||
});
|
||||
|
||||
std::string mount_options_body = "\nUse [Space] to de/select the desired mount\noptions and review carefully. Please do not\nselect multiple versions of the same option.\n";
|
||||
auto global = Container::Vertical({
|
||||
Renderer([&] { return detail::multiline_text(utils::make_multiline(mount_options_body)); }),
|
||||
Renderer([] { return separator(); }),
|
||||
content,
|
||||
Renderer([] { return separator(); }),
|
||||
controls,
|
||||
});
|
||||
|
||||
auto renderer = Renderer(global, [&] {
|
||||
const auto& file_sys_formatted = utils::exec(fmt::format("echo {} | sed \"s/.*\\.//g;s/-.*//g\"", file_sys));
|
||||
const auto& title = fmt::format("New CLI Installer | {}", file_sys_formatted);
|
||||
return detail::centered_interative_multi(title, global);
|
||||
});
|
||||
|
||||
screen.Loop(renderer);
|
||||
static constexpr auto mount_options_body = "\nUse [Space] to de/select the desired mount\noptions and review carefully. Please do not\nselect multiple versions of the same option.\n";
|
||||
detail::checklist_widget(fs_opts, ok_callback, fs_opts_state.get(), &screen, mount_options_body, fs_title, {content_size, nothing});
|
||||
|
||||
// Now clean up the file
|
||||
mount_opts_info = utils::exec(fmt::format("echo \"{}\" | sed \'s/ /,/g\'", mount_opts_info));
|
||||
@ -1651,7 +1553,7 @@ void make_esp() noexcept {
|
||||
answer = radiobox_list[static_cast<std::size_t>(selected)];
|
||||
screen.ExitLoopClosure()();
|
||||
};
|
||||
detail::radiolist_widget(radiobox_list, ok_callback, &selected, &screen, MntUefiMessage, detail::WidgetBoxSize{.text_size = nothing});
|
||||
detail::radiolist_widget(radiobox_list, ok_callback, &selected, &screen, MntUefiMessage, {.text_size = nothing});
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
@ -1824,7 +1726,7 @@ void mount_partitions() noexcept {
|
||||
if (partition == "Done") {
|
||||
make_esp();
|
||||
utils::get_cryptroot();
|
||||
// get_cryptboot();
|
||||
utils::get_cryptboot();
|
||||
return;
|
||||
}
|
||||
config_data["MOUNT"] = "";
|
||||
|
124
src/utils.cpp
124
src/utils.cpp
@ -32,7 +32,6 @@
|
||||
#include <range/v3/algorithm/for_each.hpp>
|
||||
#include <range/v3/algorithm/reverse.hpp>
|
||||
#include <range/v3/algorithm/search.hpp>
|
||||
#include <range/v3/core.hpp>
|
||||
#include <range/v3/view/filter.hpp>
|
||||
#include <range/v3/view/split.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
@ -71,7 +70,6 @@ namespace ranges = std::ranges;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace utils {
|
||||
static constexpr std::int32_t CONNECTION_TIMEOUT = 15;
|
||||
|
||||
bool is_connected() noexcept {
|
||||
#ifdef NDEVENV
|
||||
@ -383,60 +381,101 @@ void get_cryptroot() noexcept {
|
||||
auto& config_data = config_instance->data();
|
||||
|
||||
// Identify if /mnt or partition is type "crypt" (LUKS on LVM, or LUKS alone)
|
||||
if ((utils::exec("lsblk | sed -r 's/^[^[:alnum:]]+//' | awk '/\\/mnt$/ {print $6}' | grep -q crypt", true) == "0")
|
||||
|| (utils::exec("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt$/,/part/p\" | awk '{print $6}' | grep -q crypt", true) == "0")) {
|
||||
config_data["LUKS"] = 1;
|
||||
auto& luks_name = std::get<std::string>(config_data["LUKS_ROOT_NAME"]);
|
||||
const auto& luks_dev = std::get<std::string>(config_data["LUKS_DEV"]);
|
||||
luks_name = utils::exec("mount | awk '/\\/mnt / {print $1}' | sed s~/dev/mapper/~~g | sed s~/dev/~~g");
|
||||
// Get the name of the Luks device
|
||||
if (utils::exec("lsblk -i | grep -q -e \"crypt /mnt\"", true) != "0") {
|
||||
// Mountpoint is not directly on LUKS device, so we need to get the crypt device above the mountpoint
|
||||
luks_name = utils::exec("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt$/,/crypt/p\" | awk '/crypt/ {print $1}'");
|
||||
}
|
||||
if ((utils::exec("lsblk | sed -r 's/^[^[:alnum:]]+//' | awk '/\\/mnt$/ {print $6}' | grep -q crypt", true) != "0")
|
||||
|| (utils::exec("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt$/,/part/p\" | awk '{print $6}' | grep -q crypt", true) != "0")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& check_cryptparts = [&](const auto cryptparts, auto functor) {
|
||||
for (const auto& cryptpart : cryptparts) {
|
||||
if (!utils::exec(fmt::format("lsblk -lno NAME {} | grep \"{}\"", cryptpart, luks_name)).empty()) {
|
||||
functor(cryptpart);
|
||||
return true;
|
||||
}
|
||||
config_data["LUKS"] = 1;
|
||||
auto& luks_name = std::get<std::string>(config_data["LUKS_ROOT_NAME"]);
|
||||
luks_name = utils::exec("mount | awk '/\\/mnt / {print $1}' | sed s~/dev/mapper/~~g | sed s~/dev/~~g");
|
||||
// Get the name of the Luks device
|
||||
if (utils::exec("lsblk -i | grep -q -e \"crypt /mnt\"", true) != "0") {
|
||||
// Mountpoint is not directly on LUKS device, so we need to get the crypt device above the mountpoint
|
||||
luks_name = utils::exec("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt$/,/crypt/p\" | awk '/crypt/ {print $1}'");
|
||||
}
|
||||
|
||||
const auto& check_cryptparts = [&luks_name](const auto& cryptparts, auto functor) {
|
||||
for (const auto& cryptpart : cryptparts) {
|
||||
if (!utils::exec(fmt::format("lsblk -lno NAME {} | grep \"{}\"", cryptpart, luks_name)).empty()) {
|
||||
functor(cryptpart);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Check if LUKS on LVM (parent = lvm /dev/mapper/...)
|
||||
auto cryptparts = utils::make_multiline(utils::exec("lsblk -lno NAME,FSTYPE,TYPE,MOUNTPOINT | grep \"lvm\" | grep \"/mnt$\" | grep -i \"crypto_luks\" | uniq | awk '{print \"/dev/mapper/\"$1}'"));
|
||||
auto check_functor = [&](const auto cryptpart) {
|
||||
// Check if LUKS on LVM (parent = lvm /dev/mapper/...)
|
||||
auto temp_out = utils::exec("lsblk -lno NAME,FSTYPE,TYPE,MOUNTPOINT | grep \"lvm\" | grep \"/mnt$\" | grep -i \"crypto_luks\" | uniq | awk '{print \"/dev/mapper/\"$1}'");
|
||||
if (!temp_out.empty()) {
|
||||
const auto& cryptparts = utils::make_multiline(temp_out);
|
||||
const auto& check_functor = [&](const auto cryptpart) {
|
||||
config_data["LUKS_DEV"] = fmt::format("cryptdevice={}:{}", cryptpart, luks_name);
|
||||
config_data["LVM"] = 1;
|
||||
};
|
||||
if (check_cryptparts(cryptparts, check_functor)) {
|
||||
return;
|
||||
}
|
||||
check_cryptparts(cryptparts, check_functor);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if LVM on LUKS
|
||||
cryptparts = utils::make_multiline(utils::exec("lsblk -lno NAME,FSTYPE,TYPE | grep \" crypt$\" | grep -i \"LVM2_member\" | uniq | awk '{print \"/dev/mapper/\"$1}'"));
|
||||
const auto& check_lvm_luks_dev = [&]([[maybe_unused]] const auto cryptpart) {
|
||||
// Check if LVM on LUKS
|
||||
temp_out = utils::exec("lsblk -lno NAME,FSTYPE,TYPE | grep \" crypt$\" | grep -i \"LVM2_member\" | uniq | awk '{print \"/dev/mapper/\"$1}'");
|
||||
if (!temp_out.empty()) {
|
||||
const auto& cryptparts = utils::make_multiline(temp_out);
|
||||
const auto& check_functor = [&]([[maybe_unused]] const auto cryptpart) {
|
||||
auto& luks_uuid = std::get<std::string>(config_data["LUKS_UUID"]);
|
||||
luks_uuid = utils::exec("lsblk -ino NAME,FSTYPE,TYPE,MOUNTPOINT,UUID | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt /,/part/p\" | awk '/crypto_LUKS/ {print $4}'");
|
||||
config_data["LUKS_DEV"] = fmt::format("cryptdevice=UUID={}:{}", luks_uuid, luks_name);
|
||||
config_data["LVM"] = 1;
|
||||
};
|
||||
if (check_cryptparts(cryptparts, check_lvm_luks_dev)) {
|
||||
return;
|
||||
}
|
||||
check_cryptparts(cryptparts, check_functor);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if LUKS alone (parent = part /dev/...)
|
||||
cryptparts = utils::make_multiline(utils::exec("lsblk -lno NAME,FSTYPE,TYPE,MOUNTPOINT | grep \"/mnt$\" | grep \"part\" | grep -i \"crypto_luks\" | uniq | awk '{print \"/dev/\"$1}'"));
|
||||
const auto& check_func_dev = [&](const auto cryptpart) {
|
||||
// Check if LUKS alone (parent = part /dev/...)
|
||||
temp_out = utils::exec("lsblk -lno NAME,FSTYPE,TYPE,MOUNTPOINT | grep \"/mnt$\" | grep \"part\" | grep -i \"crypto_luks\" | uniq | awk '{print \"/dev/\"$1}'");
|
||||
if (!temp_out.empty()) {
|
||||
const auto& cryptparts = utils::make_multiline(temp_out);
|
||||
const auto& check_functor = [&](const auto cryptpart) {
|
||||
auto& luks_uuid = std::get<std::string>(config_data["LUKS_UUID"]);
|
||||
luks_uuid = utils::exec(fmt::format("lsblk -lno UUID,TYPE,FSTYPE {} | grep \"part\" | grep -i \"crypto_luks\" | {}", cryptpart, "awk '{print $1}'"));
|
||||
config_data["LUKS_DEV"] = fmt::format("cryptdevice=UUID={}:{}", luks_uuid, luks_name);
|
||||
};
|
||||
if (check_cryptparts(cryptparts, check_func_dev)) {
|
||||
return;
|
||||
}
|
||||
check_cryptparts(cryptparts, check_functor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void get_cryptboot() noexcept {
|
||||
auto* config_instance = Config::instance();
|
||||
auto& config_data = config_instance->data();
|
||||
|
||||
// If /boot is encrypted
|
||||
if ((utils::exec("lsblk | sed -r 's/^[^[:alnum:]]+//' | awk '/\\/mnt\\/boot$/ {print $6}' | grep -q crypt", true) != "0")
|
||||
|| (utils::exec("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt\\/boot$/,/part/p\" | awk '{print $6}' | grep -q crypt", true) != "0")) {
|
||||
return;
|
||||
}
|
||||
config_data["LUKS"] = 1;
|
||||
|
||||
// Mountpoint is directly on the LUKS device, so LUKS deivece is the same as root name
|
||||
std::string boot_name{utils::exec("mount | awk '/\\/mnt\\/boot / {print $1}' | sed s~/dev/mapper/~~g | sed s~/dev/~~g")};
|
||||
// Get UUID of the encrypted /boot
|
||||
std::string boot_uuid{utils::exec("lsblk -lno UUID,MOUNTPOINT | awk '/\\mnt\\/boot$/ {print $1}'")};
|
||||
|
||||
// Get the name of the Luks device
|
||||
if (utils::exec("lsblk -i | grep -q -e \"crypt /mnt\"", true) != "0") {
|
||||
// Mountpoint is not directly on LUKS device, so we need to get the crypt device above the mountpoint
|
||||
boot_name = utils::exec("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt\\/boot$/,/crypt/p\" | awk '/crypt/ {print $1}'");
|
||||
boot_uuid = utils::exec("lsblk -ino NAME,FSTYPE,TYPE,MOUNTPOINT,UUID | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/\\/mnt\\/boot /,/part/p\" | awk '/crypto_LUKS/ {print $4}'");
|
||||
}
|
||||
|
||||
// Check if LVM on LUKS
|
||||
if (utils::exec("lsblk -lno TYPE,MOUNTPOINT | grep \"/mnt/boot$\" | grep -q lvm", true) == "0") {
|
||||
config_data["LVM"] = 1;
|
||||
}
|
||||
|
||||
// Add cryptdevice to LUKS_DEV, if not already present (if on same LVM on LUKS as /)
|
||||
auto& luks_dev = std::get<std::string>(config_data["LUKS_DEV"]);
|
||||
const auto& found = ranges::search(luks_dev, boot_uuid);
|
||||
if (found.empty()) {
|
||||
luks_dev = fmt::format("{} cryptdevice=UUID={}:{}", luks_dev, boot_uuid, boot_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -538,9 +577,11 @@ void id_system() noexcept {
|
||||
}
|
||||
|
||||
bool handle_connection() noexcept {
|
||||
bool connected{};
|
||||
bool connected{utils::is_connected()};
|
||||
|
||||
if (!(connected = utils::is_connected())) {
|
||||
#ifdef NDEVENV
|
||||
static constexpr std::int32_t CONNECTION_TIMEOUT = 15;
|
||||
if (!connected) {
|
||||
warning_inter("An active network connection could not be detected, waiting 15 seconds ...\n");
|
||||
|
||||
std::int32_t time_waited{};
|
||||
@ -568,7 +609,6 @@ bool handle_connection() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NDEVENV
|
||||
if (connected) {
|
||||
utils::exec("yes | pacman -Sy --noconfirm", true);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace utils {
|
||||
void print_banner() noexcept;
|
||||
|
||||
[[nodiscard]] bool is_connected() noexcept;
|
||||
bool prompt_char(const char* prompt, const char* color = RESET, char* read = nullptr) noexcept;
|
||||
void clear_screen() noexcept;
|
||||
|
@ -137,15 +137,12 @@ void msgbox_widget(const std::string_view& content, Decorator boxsize) noexcept
|
||||
auto button_option = ButtonOption();
|
||||
button_option.border = false;
|
||||
auto button_back = Button("OK", screen.ExitLoopClosure(), &button_option);
|
||||
/* clang-format on */
|
||||
|
||||
auto container = Container::Horizontal({
|
||||
button_back,
|
||||
});
|
||||
|
||||
auto container = Container::Horizontal({button_back});
|
||||
auto renderer = Renderer(container, [&] {
|
||||
return centered_widget(container, "New CLI Installer", multiline_text(utils::make_multiline(content.data())) | hcenter | boxsize);
|
||||
return centered_widget(container, "New CLI Installer", multiline_text(utils::make_multiline(content)) | boxsize);
|
||||
});
|
||||
/* clang-format on */
|
||||
|
||||
screen.Loop(renderer);
|
||||
}
|
||||
@ -298,9 +295,10 @@ void radiolist_widget(const std::vector<std::string>& entries, const std::functi
|
||||
auto radiolist = Container::Vertical({
|
||||
Radiobox(&entries, selected),
|
||||
});
|
||||
auto content = Renderer(radiolist, [&] {
|
||||
|
||||
auto content = Renderer(radiolist, [&] {
|
||||
return radiolist->Render() | center | widget_sizes.content_size;
|
||||
});
|
||||
});
|
||||
|
||||
ButtonOption button_option{.border = false};
|
||||
auto controls_container = controls_widget({"OK", "Cancel"}, {ok_callback, screen->ExitLoopClosure()}, &button_option);
|
||||
@ -332,4 +330,40 @@ void radiolist_widget(const std::vector<std::string>& entries, const std::functi
|
||||
screen->Loop(renderer);
|
||||
}
|
||||
|
||||
void checklist_widget(const std::vector<std::string>& opts, const std::function<void()>&& ok_callback, bool* opts_state, ScreenInteractive* screen, const std::string_view& text, const std::string_view& title, const WidgetBoxSize widget_sizes) noexcept {
|
||||
auto checklist{Container::Vertical(detail::from_vector_checklist(opts, opts_state))};
|
||||
auto content = Renderer(checklist, [&] {
|
||||
return checklist->Render() | center | widget_sizes.content_size;
|
||||
});
|
||||
|
||||
ButtonOption button_option{.border = false};
|
||||
auto controls_container = controls_widget({"OK", "Cancel"}, {ok_callback, screen->ExitLoopClosure()}, &button_option);
|
||||
|
||||
auto controls = Renderer(controls_container, [&] {
|
||||
return controls_container->Render() | hcenter | size(HEIGHT, LESS_THAN, 3) | size(WIDTH, GREATER_THAN, 25);
|
||||
});
|
||||
|
||||
Components children{};
|
||||
if (!text.empty()) {
|
||||
children = {
|
||||
Renderer([&] { return detail::multiline_text(utils::make_multiline(text)) | widget_sizes.text_size; }),
|
||||
Renderer([] { return separator(); }),
|
||||
content,
|
||||
Renderer([] { return separator(); }),
|
||||
controls};
|
||||
} else {
|
||||
children = {
|
||||
content,
|
||||
Renderer([] { return separator(); }),
|
||||
controls};
|
||||
}
|
||||
auto global{Container::Vertical(children)};
|
||||
|
||||
auto renderer = Renderer(global, [&] {
|
||||
return centered_interative_multi(title, global);
|
||||
});
|
||||
|
||||
screen->Loop(renderer);
|
||||
}
|
||||
|
||||
} // namespace tui::detail
|
||||
|
@ -30,13 +30,14 @@ namespace detail {
|
||||
auto from_vector_checklist(const std::vector<std::string>& opts, bool* opts_state) noexcept -> ftxui::Components;
|
||||
auto from_checklist_string(const std::vector<std::string>& opts, bool* opts_state) noexcept -> std::string;
|
||||
auto from_checklist_vector(const std::vector<std::string>& opts, bool* opts_state) noexcept -> std::vector<std::string>;
|
||||
void msgbox_widget(const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
|
||||
void msgbox_widget(const std::string_view& content, ftxui::Decorator boxsize = ftxui::hcenter | size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
|
||||
bool inputbox_widget(std::string& value, const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5), bool password = false) noexcept;
|
||||
void infobox_widget(const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
|
||||
bool yesno_widget(const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
|
||||
bool yesno_widget(ftxui::Component& container, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
|
||||
void menu_widget(const std::vector<std::string>& entries, const std::function<void()>&& ok_callback, std::int32_t* selected, ftxui::ScreenInteractive* screen, const std::string_view& text = "", const WidgetBoxSize widget_sizes = {}) noexcept;
|
||||
void radiolist_widget(const std::vector<std::string>& entries, const std::function<void()>&& ok_callback, std::int32_t* selected, ftxui::ScreenInteractive* screen, const std::string_view& text = "", const WidgetBoxSize widget_sizes = {}) noexcept;
|
||||
void checklist_widget(const std::vector<std::string>& opts, const std::function<void()>&& ok_callback, bool* opts_state, ftxui::ScreenInteractive* screen, const std::string_view& text = "", const std::string_view& title = "New CLI Installer", const WidgetBoxSize widget_sizes = {}) noexcept;
|
||||
} // namespace detail
|
||||
} // namespace tui
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user