#!/usr/bin/env bash # OmniXY NixOS Installation Script # Stylized installer with Tokyo Night theme integration set -e # Get terminal dimensions for centering TERM_WIDTH=$(tput cols 2>/dev/null || echo 80) TERM_HEIGHT=$(tput lines 2>/dev/null || echo 24) # Tokyo Night Color Palette (using printf for better compatibility) setup_colors() { BG=$(printf '\033[48;2;26;27;38m') # #1a1b26 FG=$(printf '\033[38;2;192;202;245m') # #c0caf5 BLUE=$(printf '\033[38;2;122;162;247m') # #7aa2f7 CYAN=$(printf '\033[38;2;125;207;255m') # #7dcfff GREEN=$(printf '\033[38;2;158;206;106m') # #9ece6a YELLOW=$(printf '\033[38;2;224;175;104m') # #e0af68 RED=$(printf '\033[38;2;247;118;142m') # #f7768e PURPLE=$(printf '\033[38;2;187;154;247m') # #bb9af7 ORANGE=$(printf '\033[38;2;255;158;100m') # #ff9e64 DARK_BLUE=$(printf '\033[38;2;65;72;104m') # #414868 # Special effects BOLD=$(printf '\033[1m') DIM=$(printf '\033[2m') UNDERLINE=$(printf '\033[4m') BLINK=$(printf '\033[5m') RESET=$(printf '\033[0m') CLEAR=$(printf '\033[2J') CURSOR_HOME=$(printf '\033[H') } # Initialize colors setup_colors # Utility functions center_text() { local text="$1" local width=${2:-$TERM_WIDTH} # Strip ANSI codes for accurate length calculation local clean_text=$(echo "$text" | sed 's/\x1b\[[0-9;]*m//g') local padding=$(( (width - ${#clean_text}) / 2 )) if [ $padding -gt 0 ]; then printf "%*s%b\n" $padding "" "$text" else printf "%b\n" "$text" fi } progress_bar() { local progress=$1 local width=50 local filled=$((progress * width / 100)) local empty=$((width - filled)) printf "\r${BLUE}[" printf "%*s" $filled | tr ' ' '█' printf "%*s" $empty | tr ' ' '░' printf "] ${CYAN}%d%%${RESET}" $progress } animate_text() { local text="$1" local color="$2" local delay=${3:-0.03} for ((i=0; i<${#text}; i++)); do printf "${color}%c" "${text:$i:1}" sleep $delay done printf "${RESET}" } loading_spinner() { local pid=$1 local message="$2" local spinner='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' local i=0 while kill -0 $pid 2>/dev/null; do printf "\r${CYAN}%c ${FG}%s${RESET}" "${spinner:$i:1}" "$message" i=$(( (i+1) % ${#spinner} )) sleep 0.1 done printf "\r${GREEN}✓ ${FG}%s${RESET}\n" "$message" } # Set terminal background and clear setup_terminal() { printf "${CLEAR}${CURSOR_HOME}" # Don't set background color as it may not work in all terminals } # Stylized banner with proper escaping show_banner() { clear setup_terminal # Add some vertical spacing for ((i=0; i<3; i++)); do echo; done # Main logo - using simpler ASCII that works better echo center_text "${CYAN}${BOLD} ██████╗ ███╗ ███╗███╗ ██╗██╗██╗ ██╗██╗ ██╗" center_text "██╔═══██╗████╗ ████║████╗ ██║██║╚██╗██╔╝╚██╗ ██╔╝" center_text "${BLUE}██║ ██║██╔████╔██║██╔██╗ ██║██║ ╚███╔╝ ╚████╔╝ " center_text "██║ ██║██║╚██╔╝██║██║╚██╗██║██║ ██╔██╗ ╚██╔╝ " center_text "${PURPLE}╚██████╔╝██║ ╚═╝ ██║██║ ╚████║██║██╔╝ ██╗ ██║ " center_text " ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝ ╚═╝ ${RESET}" echo # Subtitle with typewriter effect printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) "" animate_text "🚀 Declarative • 🎨 Beautiful • ⚡ Fast" "$CYAN" 0.05 echo echo # Version and edition info center_text "${DIM}${FG}NixOS Edition • Version 1.0 • Tokyo Night Theme${RESET}" echo # Decorative border printf "%*s" $(( (TERM_WIDTH - 60) / 2 )) "" printf "${DARK_BLUE}" for ((i=0; i<60; i++)); do printf "═"; done printf "${RESET}\n" echo } # Stylized section headers section_header() { local title="$1" local icon="$2" local width=60 echo printf "%*s" $(( (TERM_WIDTH - width) / 2 )) "" printf "${BLUE}╭" for ((i=0; i/dev/null && sleep 0.3) & loading_spinner $! "Updating home configuration" (sudo sed -i "s|home.homeDirectory = \"/home/user\"|home.homeDirectory = \"/home/$username\"|" /etc/nixos/home.nix 2>/dev/null && sleep 0.3) & loading_spinner $! "Setting home directory" } # Stylized theme selection select_theme() { section_header "Theme Selection" "🎨" local themes=( "🌃 Tokyo Night - Dark theme with vibrant colors" "🎀 Catppuccin - Pastel theme with modern aesthetics" "🟤 Gruvbox - Retro theme with warm colors" "❄️ Nord - Arctic theme with cool colors" "🌲 Everforest - Green forest theme" "🌹 Rose Pine - Cozy theme with muted colors" "🌊 Kanagawa - Japanese-inspired theme" "☀️ Catppuccin Latte - Light variant" "⚫ Matte Black - Minimalist dark theme" "💎 Osaka Jade - Jade green theme" "☕ Ristretto - Coffee-inspired theme" ) for i in "${!themes[@]}"; do local num=$((i + 1)) center_text "${BOLD}${CYAN}$num.${RESET}${FG} ${themes[$i]}" done echo local theme_choice theme_choice=$(get_input "Select theme (1-11)" "1" '[[ $1 =~ ^[1-9]$|^1[01]$ ]]') local theme_names=("tokyo-night" "catppuccin" "gruvbox" "nord" "everforest" "rose-pine" "kanagawa" "catppuccin-latte" "matte-black" "osaka-jade" "ristretto") local selected_theme=${theme_names[$((theme_choice - 1))]} echo center_text "${FG}Selected theme: ${CYAN}${BOLD}$selected_theme${RESET}" (sudo sed -i "s/currentTheme = \".*\"/currentTheme = \"$selected_theme\"/" /etc/nixos/configuration.nix && sleep 0.5) & loading_spinner $! "Applying theme configuration" } # Feature configuration configure_features() { section_header "Feature Configuration" "⚙️ " center_text "${FG}Configure optional features:${RESET}" echo # Security features center_text "${BOLD}${PURPLE}Security Features:${RESET}" printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) "" printf "${CYAN}Enable fingerprint authentication? (y/N): ${RESET}" read -n 1 -r reply echo if [[ $reply =~ ^[Yy]$ ]]; then center_text "${GREEN}✅ Fingerprint authentication enabled${RESET}" sudo sed -i 's/fingerprint = {/fingerprint = {\n enable = true;/' /etc/nixos/configuration.nix fi printf "%*s" $(( (TERM_WIDTH - 35) / 2 )) "" printf "${CYAN}Enable FIDO2 security keys? (y/N): ${RESET}" read -n 1 -r reply echo if [[ $reply =~ ^[Yy]$ ]]; then center_text "${GREEN}✅ FIDO2 authentication enabled${RESET}" sudo sed -i 's/fido2 = {/fido2 = {\n enable = true;/' /etc/nixos/configuration.nix fi echo center_text "${BOLD}${BLUE}Development Features:${RESET}" printf "%*s" $(( (TERM_WIDTH - 30) / 2 )) "" printf "${CYAN}Enable Docker support? (y/N): ${RESET}" read -n 1 -r reply echo if [[ $reply =~ ^[Yy]$ ]]; then center_text "${GREEN}✅ Docker support enabled${RESET}" # Add Docker configuration fi echo center_text "${BOLD}${YELLOW}Gaming Features:${RESET}" printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) "" printf "${CYAN}Enable gaming support (Steam, Wine)? (y/N): ${RESET}" read -n 1 -r reply echo if [[ $reply =~ ^[Yy]$ ]]; then center_text "${GREEN}✅ Gaming support enabled${RESET}" # Add gaming configuration fi } # Hardware configuration generation generate_hardware_config() { section_header "Hardware Configuration" "🔧" if [ ! -f /etc/nixos/hardware-configuration.nix ]; then center_text "${FG}Generating hardware-specific configuration...${RESET}" echo (sudo nixos-generate-config --root / && sleep 1) & loading_spinner $! "Scanning hardware configuration" else center_text "${YELLOW}⚠️ Hardware configuration already exists${RESET}" center_text "${DIM}${FG}Skipping hardware generation...${RESET}" sleep 1 fi } # System building with enhanced progress build_system() { section_header "System Build" "🏗️ " center_text "${YELLOW}${BOLD}⚠️ IMPORTANT NOTICE ⚠️${RESET}" center_text "${FG}This process may take 10-45 minutes depending on your system${RESET}" center_text "${FG}A stable internet connection is required${RESET}" echo printf "%*s" $(( (TERM_WIDTH - 30) / 2 )) "" printf "${CYAN}Continue with system build? (Y/n): ${RESET}" read -n 1 -r reply echo if [[ $reply =~ ^[Nn]$ ]]; then center_text "${YELLOW}Build postponed. Run this command later:${RESET}" center_text "${CYAN}sudo nixos-rebuild switch --flake /etc/nixos#omnixy${RESET}" return fi echo center_text "${FG}Building NixOS system configuration...${RESET}" center_text "${DIM}${FG}This includes downloading packages and compiling the system${RESET}" echo # Start build in background and show spinner sudo nixos-rebuild switch --flake /etc/nixos#omnixy & local build_pid=$! # Enhanced progress indication local dots="" local build_messages=( "Downloading Nix packages..." "Building system dependencies..." "Compiling configuration..." "Setting up services..." "Finalizing installation..." ) local msg_index=0 local counter=0 while kill -0 $build_pid 2>/dev/null; do if (( counter % 30 == 0 && msg_index < ${#build_messages[@]} )); then echo center_text "${CYAN}${build_messages[$msg_index]}${RESET}" ((msg_index++)) fi printf "\r%*s${CYAN}Building system" $(( (TERM_WIDTH - 20) / 2 )) "" dots+="." if [ ${#dots} -gt 6 ]; then dots=""; fi printf "%s${RESET}" "$dots" sleep 1 ((counter++)) done wait $build_pid local exit_code=$? echo if [ $exit_code -eq 0 ]; then center_text "${GREEN}${BOLD}✅ System build completed successfully!${RESET}" else center_text "${RED}${BOLD}❌ Build failed with errors${RESET}" center_text "${FG}Check the output above for details${RESET}" exit $exit_code fi } # Completion screen show_complete() { clear setup_terminal # Add spacing for ((i=0; i<2; i++)); do echo; done # Success banner printf "%*s${GREEN}${BOLD}" $(( (TERM_WIDTH - 60) / 2 )) "" echo "╭──────────────────────────────────────────────────────────╮" printf "%*s${GREEN}│" $(( (TERM_WIDTH - 60) / 2 )) "" printf "%*s🎉 OmniXY Installation Complete! 🎉%*s│\n" 14 "" 14 "" printf "%*s${GREEN}╰──────────────────────────────────────────────────────────╯${RESET}\n" $(( (TERM_WIDTH - 60) / 2 )) "" echo echo # Quick start section section_header "Quick Start Guide" "🚀" center_text "${CYAN}${BOLD}Essential Commands:${RESET}" center_text "${FG}${DIM}Run these commands to get started${RESET}" echo center_text "${CYAN}omnixy-menu${RESET} ${FG}- Interactive system menu${RESET}" center_text "${CYAN}omnixy-info${RESET} ${FG}- System information display${RESET}" center_text "${CYAN}omnixy-theme${RESET} ${FG}- Switch between themes${RESET}" center_text "${CYAN}omnixy-security${RESET} ${FG}- Configure security features${RESET}" echo section_header "Keyboard Shortcuts" "⌨️ " center_text "${PURPLE}${BOLD}Hyprland Window Manager:${RESET}" echo center_text "${CYAN}Super + Return${RESET} ${FG}- Open terminal${RESET}" center_text "${CYAN}Super + R${RESET} ${FG}- Application launcher${RESET}" center_text "${CYAN}Super + B${RESET} ${FG}- Web browser${RESET}" center_text "${CYAN}Super + E${RESET} ${FG}- File manager${RESET}" center_text "${CYAN}Super + Q${RESET} ${FG}- Close window${RESET}" echo section_header "Next Steps" "📋" center_text "${YELLOW}${BOLD}Recommended Actions:${RESET}" echo center_text "${FG}1. ${CYAN}Reboot your system${RESET} ${FG}- Apply all changes${RESET}" center_text "${FG}2. ${CYAN}Run omnixy-security status${RESET} ${FG}- Check security setup${RESET}" center_text "${FG}3. ${CYAN}Configure fingerprint/FIDO2${RESET} ${FG}- Enhanced security${RESET}" center_text "${FG}4. ${CYAN}Explore themes${RESET} ${FG}- Try different color schemes${RESET}" echo center_text "${BLUE}${UNDERLINE}https://github.com/TheArctesian/omnixy${RESET} ${FG}- Project homepage${RESET}" echo center_text "${DIM}${FG}Thank you for choosing OmniXY! ${CYAN}❤️${RESET}" echo # Auto-reboot prompt printf "%*s${YELLOW}Reboot now to complete installation? (Y/n): ${RESET}" $(( (TERM_WIDTH - 45) / 2 )) "" read -n 1 -r reply echo if [[ ! $reply =~ ^[Nn]$ ]]; then center_text "${GREEN}Rebooting in 3 seconds...${RESET}" sleep 1 center_text "${GREEN}Rebooting in 2 seconds...${RESET}" sleep 1 center_text "${GREEN}Rebooting in 1 second...${RESET}" sleep 1 sudo reboot else center_text "${FG}Remember to reboot when convenient!${RESET}" fi } # Main installation orchestrator main() { # Trap to restore terminal on exit trap 'printf "\033[0m\033[?25h"; stty sane 2>/dev/null || true' EXIT # Hide cursor during installation printf '\033[?25l' show_banner sleep 2 section_header "Welcome to OmniXY" "🌟" center_text "${FG}Transform your NixOS into a beautiful, modern desktop experience${RESET}" center_text "${DIM}${FG}This installer will guide you through the complete setup process${RESET}" echo printf "%*s${CYAN}${BOLD}Ready to begin installation? (Y/n): ${RESET}" $(( (TERM_WIDTH - 35) / 2 )) "" read -n 1 -r reply echo if [[ $reply =~ ^[Nn]$ ]]; then center_text "${FG}Installation cancelled. Come back anytime!${RESET}" exit 0 fi # Installation flow with enhanced UX check_nixos backup_config install_config generate_hardware_config update_user select_theme configure_features build_system show_complete # Restore cursor printf '\033[?25h' } # Start the installation main "$@"