#!/usr/bin/env bash # Preview Omarchy installer UI concepts without building or booting the ISO. # Usage: bin/omarchy-install-ui-preview [dashboard|matrix|forge|logs] set -euo pipefail concept="${1:-dashboard}" SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" LOGO_PATH="${OMARCHY_PREVIEW_LOGO:-}" if [[ -z $LOGO_PATH ]]; then for candidate in \ "$SCRIPT_DIR/../../omarchy-installer/logo.txt" \ "$SCRIPT_DIR/../configs/airootfs/usr/share/omarchy/logo.txt" \ "/usr/share/omarchy/logo.txt"; do if [[ -f $candidate ]]; then LOGO_PATH="$candidate" break fi done fi CSI=$'\033[' RESET="${CSI}0m" BOLD="${CSI}1m" DIM="${CSI}2m" HIDE_CURSOR="${CSI}?25l" SHOW_CURSOR="${CSI}?25h" CLEAR="${CSI}2J${CSI}H" HOME="${CSI}H" CLEAR_LINE="${CSI}2K" CLEAR_TO_END="${CSI}J" GREEN="${CSI}38;5;150m" BLUE="${CSI}38;5;111m" PURPLE="${CSI}38;5;141m" YELLOW="${CSI}38;5;221m" RED="${CSI}38;5;203m" GRAY="${CSI}38;5;245m" DARK="${CSI}38;5;238m" logo_width() { if [[ -n ${LOGO_PATH:-} && -f $LOGO_PATH ]]; then awk '{ if (length > max) max = length } END { print max+0 }' "$LOGO_PATH" else printf '78\n' fi } LOGO_WIDTH="$(logo_width)" (( LOGO_WIDTH > 0 )) || LOGO_WIDTH=78 CONTENT_WIDTH="${OMARCHY_PREVIEW_WIDTH:-$LOGO_WIDTH}" (( CONTENT_WIDTH > 0 )) || CONTENT_WIDTH="$LOGO_WIDTH" phases=( "Preparing live environment" "Partitioning target disk" "Installing base system" "Installing Omarchy packages" "Building Limine UKI" "Configuring Snapper" "Validating boot setup" "Finishing" ) logs=( "pacman-key: populating archlinux keyring" "mount: /mnt ready" "pacstrap: installing linux btrfs-progs limine" "pacman: installing omarchy" "useradd: creating ryan with /etc/skel defaults" "limine-update: generating omarchy_linux.efi" "snapper: creating root config" "efibootmgr: registered Limine" "validation: UKI present, fstab present, boot entry present" ) whimsy=( "making Linux feel like home" "installing the good defaults" "putting the system in order" "setting up a civilized desktop" "clearing the path to Hyprland" "preparing the command line sanctuary" "teaching pacman the house rules" "laying down the Tokyo Night carpet" "arranging the sharp tools safely" "keeping the boot path clean" "giving Limine the keys" "making snapshots worth having" "saving future you a few hours" "choosing boring where boring wins" "leaving room for your dotfiles" "tightening the last few screws" ) cleanup() { printf '%s%s' "$RESET" "$SHOW_CURSOR" } trap cleanup EXIT INT TERM term_cols() { # Match install/helpers/presentation.sh: read the real tty dimensions even # if stdout is redirected through a pipe/process substitution. if [[ -e /dev/tty ]]; then local size size=$(stty size 2>/dev/null /dev/null || echo 100 } term_rows() { if [[ -e /dev/tty ]]; then local size size=$(stty size 2>/dev/null /dev/null || echo 32 } repeat() { local char="$1" count="$2" local out="" for ((i=0; i= ${#phases[@]} )) && phase_idx=$((${#phases[@]} - 1)) local pct=$(( frame * 100 / 95 )) (( pct > 100 )) && pct=100 printf '%s' "$HOME" blank_line render_logo blank_line center "Phase $((phase_idx + 1))/${#phases[@]} ${phases[$phase_idx]}" "$CONTENT_WIDTH" blank_line line_at "$CONTENT_WIDTH" $(( (CONTENT_WIDTH - 40) / 2 )) "" progress_bar "$pct" 34 printf '\n' blank_line center "Now: $(current_log "$frame")" "$CONTENT_WIDTH" blank_line local spin=("◐" "◓" "◑" "◒") center "${GREEN}${spin[$((frame % 4))]} $(current_whimsy "$frame" "$phase_idx") ${RESET}" "$CONTENT_WIDTH" blank_line center "${DIM}Press Ctrl-C to quit${RESET}" "$CONTENT_WIDTH" } render_matrix() { local frame="$1" rows cols rows=$(term_rows); cols=$(term_cols) (( rows > 34 )) && rows=34 (( cols > 110 )) && cols=110 local words=(pacstrap limine btrfs snapper uki kernel hyprland omarchy archlinux) printf '%s' "$HOME" printf '%s%s' "$DIM" "$PURPLE" center "TOKYO NIGHT PACKAGE RAIN" "$cols" printf '%s' "$RESET" echo for ((r=2; r= ${#phases[@]} )) && phase_idx=$((${#phases[@]} - 1)) echo center "${BOLD}${GREEN}${phases[$phase_idx]}${RESET}" "$cols" center "${GRAY}$(current_log "$frame")${RESET}" "$cols" } render_forge() { local frame="$1" phase_idx=$(( frame / 12 )) (( phase_idx >= ${#phases[@]} )) && phase_idx=$((${#phases[@]} - 1)) local sparks=("·" "∙" "*" "✦" "✧" "⋆") local hammer=("⚒" " " "⚒" " ") local pct=$(( frame * 100 / 95 )) (( pct > 100 )) && pct=100 printf '%s' "$HOME" printf '%s' "$YELLOW" center "THE OMARCHY FORGE" 80 printf '%s\n\n' "$RESET" center " ${sparks[$((frame % 6))]} ${sparks[$(((frame+2) % 6))]} ${sparks[$(((frame+4) % 6))]}" 80 center " ${YELLOW}${hammer[$((frame % 4))]}${RESET}" 80 center " _____________" 80 center " / \\" 80 center " ____/ ARCH ROOTFS \____" 80 center " / \_______________/ \\" 80 center " / BTRFS │ LIMINE │ UKI \\" 80 center " \_________│__________│______/" 80 echo center "${GREEN}${phases[$phase_idx]}${RESET}" 80 echo line_at 80 22 "" progress_bar "$pct" 36 echo -e "\n" center "${GRAY}$(current_log "$frame")${RESET}" 80 } render_logs() { local frame="$1" phase_idx=$(( frame / 12 )) (( phase_idx >= ${#phases[@]} )) && phase_idx=$((${#phases[@]} - 1)) local pct=$(( frame * 100 / 95 )) (( pct > 100 )) && pct=100 printf '%s' "$HOME" render_logo blank_line line_at "$CONTENT_WIDTH" 0 "${BOLD}Omarchy Install${RESET}\n" line_at "$CONTENT_WIDTH" 0 "" progress_bar "$pct" 50 printf '\n' blank_line line_at "$CONTENT_WIDTH" 0 "${GREEN}${phases[$phase_idx]}${RESET}\n" blank_line local start=$(( frame - 12 )) (( start < 0 )) && start=0 for ((i=start; i<=frame; i++)); do line_at "$CONTENT_WIDTH" 2 "${GRAY}→${RESET} [$(printf '%02d:%02d' "$((i / 3))" "$(((i * 7) % 60))")] $(current_log "$i")\n" done blank_line line_at "$CONTENT_WIDTH" 0 "${DIM}This is the boring/debuggable mode: curated progress plus log tail.${RESET}\n" } case "$concept" in dashboard|matrix|forge|logs) ;; -h|--help|help) echo "Usage: $0 [dashboard|matrix|forge|logs]" exit 0 ;; *) echo "Unknown concept: $concept" >&2 echo "Usage: $0 [dashboard|matrix|forge|logs]" >&2 exit 2 ;; esac printf '%s%s' "$HIDE_CURSOR" "$CLEAR" for ((frame=0; frame<=96; frame++)); do "render_$concept" "$frame" printf '%s' "$CLEAR_TO_END" sleep 0.08 done