diff --git a/data/com.github.pikaos-linux.pikafirstsetup.gschema.xml b/data/com.github.pikaos-linux.pikafirstsetup.gschema.xml
new file mode 100644
index 0000000..ca66877
--- /dev/null
+++ b/data/com.github.pikaos-linux.pikafirstsetup.gschema.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ 1200
+ Default window width
+
+
+ 600
+ Default window height
+
+
+ false
+ Default window maximized behaviour
+
+
+
diff --git a/src/first_setup/first_setup.rs b/src/first_setup/first_setup.rs
new file mode 100644
index 0000000..0c4fb0c
--- /dev/null
+++ b/src/first_setup/first_setup.rs
@@ -0,0 +1,70 @@
+// 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 adw::ffi::ADW_TOOLBAR_FLAT;
+use glib::*;
+use gdk::Display;
+
+//
+use std::cell::RefCell;
+use std::rc::Rc;
+use crate::connection_check::check_internet_connection;
+
+// carousel crates
+use crate::first_setup::initial_carousel::initial_carousel;
+use crate::first_setup::internet_carousel::internet_carousel;
+use crate::first_setup::update_carousel::update_carousel;
+
+pub fn first_setup(window: &adw::ApplicationWindow) {
+
+ let first_setup_carousel = adw::Carousel::builder()
+ .allow_long_swipes(false)
+ .allow_mouse_drag(false)
+ .allow_scroll_wheel(false)
+ .interactive(false)
+ .vexpand(true)
+ .hexpand(true)
+ .build();
+
+ let first_setup_carousel_indicator = adw::CarouselIndicatorDots::builder()
+ .carousel(&first_setup_carousel)
+ .build();
+
+ let first_setup_window_headerbar_back_button = gtk::Button::builder()
+ .label("Back")
+ .build();
+
+ let first_setup_window_headerbar = adw::HeaderBar::builder()
+ .show_start_title_buttons(true)
+ .title_widget(&first_setup_carousel_indicator)
+ .build();
+
+ let first_setup_window_toolbarview = adw::ToolbarView::builder()
+ .top_bar_style(ToolbarStyle::Flat)
+ .content(&first_setup_carousel)
+ .build();
+
+ let internet_connected = Rc::new(RefCell::new(false));
+
+ first_setup_window_headerbar.pack_start(&first_setup_window_headerbar_back_button);
+ first_setup_window_toolbarview.add_top_bar(&first_setup_window_headerbar);
+
+ first_setup_window_headerbar_back_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
+ let first_setup_prev_page = first_setup_carousel.position() - 1.0;
+ first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(first_setup_prev_page as u32), true)
+ }));
+
+ // CAROUSELS
+
+ // Initial Carousel
+ initial_carousel(&first_setup_carousel);
+ internet_carousel(&first_setup_carousel, &internet_connected);
+ update_carousel(&first_setup_carousel, &internet_connected);
+
+ // Add file to window
+ window.set_content(Some(&first_setup_window_toolbarview))
+}
\ No newline at end of file
diff --git a/src/first_setup/initial_carousel.rs b/src/first_setup/initial_carousel.rs
new file mode 100644
index 0000000..b2498b0
--- /dev/null
+++ b/src/first_setup/initial_carousel.rs
@@ -0,0 +1,44 @@
+// 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;
+
+pub fn initial_carousel(first_setup_carousel: &adw::Carousel) {
+ let first_setup_initial_box = gtk::Box::builder()
+ // that puts items vertically
+ .orientation(Orientation::Vertical)
+ .vexpand(true)
+ .valign(Align::Center)
+ .hexpand(true)
+ .vexpand(true)
+ .build();
+
+ let first_setup_initial_box_text = adw::StatusPage::builder()
+ .icon_name("debian-swirl")
+ .title("Welcome")
+ .description("This wizard will help you finish your PikaOS installation.")
+ .build();
+ first_setup_initial_box_text.add_css_class("compact");
+
+ let first_setup_start_button = gtk::Button::builder()
+ .label("Let's Start")
+ .halign(Align::Center)
+ .build();
+
+ first_setup_start_button.add_css_class("suggested-action");
+ first_setup_start_button.add_css_class("pill");
+
+ first_setup_initial_box.append(&first_setup_initial_box_text);
+ first_setup_initial_box.append(&first_setup_start_button);
+
+ first_setup_carousel.append(&first_setup_initial_box);
+
+ first_setup_start_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
+ first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(1), true)
+ }));
+}
\ No newline at end of file
diff --git a/src/first_setup/internet_carousel.rs b/src/first_setup/internet_carousel.rs
new file mode 100644
index 0000000..7b5fb9a
--- /dev/null
+++ b/src/first_setup/internet_carousel.rs
@@ -0,0 +1,133 @@
+// 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;
+
+pub fn internet_carousel(first_setup_carousel: &adw::Carousel, internet_connected: &Rc>) {
+
+ let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
+ let internet_loop_sender = internet_loop_sender.clone();
+ // The long running operation runs now in a separate thread
+ gio::spawn_blocking(move || {
+ loop {
+ //match check_internet_connection() {
+ // Ok(_) => {
+ // internet_loop_sender.send_blocking(true).expect("The channel needs to be open.");
+ // }
+ // Err(_) => {
+ // internet_loop_sender.send_blocking(false).expect("The channel needs to be open.");
+ // }
+ //}
+ let check_internet_connection_cli = Command::new("ping")
+ .arg("ppa.pika-os.com")
+ .arg("-c 1")
+ .output()
+ .expect("failed to execute process");
+ if check_internet_connection_cli.status.success() {
+ internet_loop_sender.send_blocking(true).expect("The channel needs to be open.");
+ } else {
+ internet_loop_sender.send_blocking(false).expect("The channel needs to be open.");
+ }
+ }
+ });
+
+ let first_setup_internet_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_internet_box_text = adw::StatusPage::builder()
+ .icon_name("network-cellular-acquiring")
+ .title("Internet")
+ .description("Checking Internet Connection...")
+ .hexpand(true)
+ .vexpand(true)
+ .valign(Align::Start)
+ .build();
+ first_setup_internet_box_text.add_css_class("compact");
+
+ let internet_skip_button = gtk::Button::builder()
+ .label("Skip")
+ .halign(Align::Center)
+ .sensitive(false)
+ .build();
+
+ internet_skip_button.add_css_class("destructive-action");
+ internet_skip_button.add_css_class("pill");
+
+ let internet_next_button = gtk::Button::builder()
+ .label("Next")
+ .halign(Align::Center)
+ .sensitive(false)
+ .build();
+
+ internet_next_button.add_css_class("suggested-action");
+ internet_next_button.add_css_class("pill");
+
+ let internet_buttons_box = gtk::Box::builder()
+ .orientation(Orientation::Horizontal)
+ .halign(Align::Center)
+ .valign(Align::End)
+ .hexpand(true)
+ .margin_end(15)
+ .margin_start(15)
+ .margin_bottom(15)
+ .margin_top(15)
+ .spacing(80)
+ .build();
+
+ internet_buttons_box.append(&internet_skip_button);
+ internet_buttons_box.append(&internet_next_button);
+
+ first_setup_internet_box.append(&first_setup_internet_box_text);
+ first_setup_internet_box.append(&internet_buttons_box);
+
+ first_setup_carousel.append(&first_setup_internet_box);
+
+ let internet_connected_status = internet_connected.clone();
+
+ let internet_loop_context = MainContext::default();
+ // The main loop executes the asynchronous block
+ internet_loop_context.spawn_local(clone!(@weak internet_skip_button, @weak internet_next_button, @weak first_setup_internet_box_text => async move {
+ while let Ok(state) = internet_loop_receiver.recv().await {
+ if state == true {
+ internet_skip_button.set_sensitive(false);
+ internet_next_button.set_sensitive(true);
+ first_setup_internet_box_text.set_description(Some("Device connected to Internet Successfully!"));
+ first_setup_internet_box_text.set_icon_name(Some("network-cellular-signal-excellent"));
+ *internet_connected_status.borrow_mut()=true;
+ } else {
+ internet_next_button.set_sensitive(false);
+ internet_skip_button.set_sensitive(true);
+ first_setup_internet_box_text.set_description(Some("No internet Connection!"));
+ first_setup_internet_box_text.set_icon_name(Some("network-cellular-offline"));
+ *internet_connected_status.borrow_mut()=false;
+ }
+ }
+ }));
+
+ internet_next_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
+ first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(2), true);
+ }));
+
+ internet_skip_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
+ first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(2), true);
+ }));
+}
\ No newline at end of file
diff --git a/src/first_setup/mod.rs b/src/first_setup/mod.rs
new file mode 100644
index 0000000..bf09ffb
--- /dev/null
+++ b/src/first_setup/mod.rs
@@ -0,0 +1,5 @@
+pub mod first_setup;
+pub mod initial_carousel;
+pub mod internet_carousel;
+
+pub mod update_carousel;
\ No newline at end of file