omni/
ui.rs

1use anyhow::Result;
2use console::{style, Term};
3use dialoguer::theme::ColorfulTheme;
4use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
5use spinners::{Spinner, Spinners};
6use std::{thread, time::Duration};
7use crate::api_client::ApiClient;
8
9const LOGO: &str = r#"
10    __                      _           _____ __                   __
11  / __ \ ____ ___   ____   (_)        / ____// / __    __  __  ___/ /
12 / / / // __ `__ \ / __ \ / /  ____  / /    / // __ \ / / / // __  / 
13/ /_/ // / / / / // / / // / /____/ / /___ / // /_/ // /_/ // /_/ /  
14\____//_/ /_/ /_//_/ /_//_/         \____//_/ \____/ \__,_/ \__,_/   
15"#;
16
17// Gradient colors (simulated with different shades of blue)
18const GRADIENT_COLORS: [&str; 5] = ["#00c6ff", "#0072ff", "#0057ff", "#0053d4", "#00c6ff"];
19
20pub struct PremiumUI {
21    pub term: Term,
22    pub multi_progress: MultiProgress,
23    pub theme: ColorfulTheme,
24    pub api_client: ApiClient,
25}
26
27impl PremiumUI {
28    pub fn new() -> Self {
29        Self {
30            term: Term::stdout(),
31            multi_progress: MultiProgress::new(),
32            theme: ColorfulTheme::default(),
33            api_client: ApiClient::new(),
34        }
35    }
36
37    pub fn display_welcome(&self) -> Result<()> {
38        self.term.clear_screen()?;
39
40        // Print logo with a simulated gradient effect
41        self.print_gradient_logo();
42
43        // Print boxed CLI information that matches the screenshot
44        self.print_info_box();
45
46        Ok(())
47    }
48
49    fn print_gradient_logo(&self) {
50        // Split the logo into lines
51        let logo_lines: Vec<&str> = LOGO.trim_matches('\n').split('\n').collect();
52
53        for (i, line) in logo_lines.iter().enumerate() {
54            // Use modulo to cycle through colors for a gradient-like effect
55            let color_index = i % GRADIENT_COLORS.len();
56            println!("{}", style(line).color256(39 + color_index as u8).bold());
57        }
58        println!();
59    }
60
61    fn print_info_box(&self) {
62        println!("┌{:─^53}┐", "");
63        println!(
64            "│ {}{}│",
65            style("OMNICLOUD CLI").bold().cyan(),
66            " ".repeat(39)
67        );
68        println!(
69            "│ {} {}{}│",
70            style("Version").dim(),
71            style(version::version!()).dim(),
72            " ".repeat(39)
73        );
74        println!("│{}│", " ".repeat(53));
75        println!(
76            "│ {} Type {} to see available commands{}│",
77            style("→").cyan(),
78            style("omni help").green(),
79            " ".repeat(10)
80        );
81        println!(
82            "│ {} Documentation: {}{}│",
83            style("→").cyan(),
84            style("https://docs.omnicloud.sh").cyan(),
85            " ".repeat(10)
86        );
87        println!(
88            "│ {} Support: {}{}│",
89            style("→").cyan(),
90            style("[email protected]").cyan(),
91            " ".repeat(21)
92        );
93        println!("└{:─^53}┘", "");
94        println!();
95    }
96
97    fn print_status_indicators(&self) {
98        // These are removed based on the screenshot
99    }
100
101    fn show_initializing_spinner(&self) -> Result<()> {
102        // Removed the initialization spinner as requested
103        Ok(())
104    }
105
106    pub fn create_spinner(&self, message: &str) -> Spinner {
107        Spinner::with_timer(Spinners::Dots12, message.into())
108    }
109
110    pub fn create_progress_bar(&self, len: u64, message: &str) -> ProgressBar {
111        let pb = self.multi_progress.add(ProgressBar::new(len));
112        pb.set_style(ProgressStyle::default_bar()
113            .template("{spinner:.green} [{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}")
114            .unwrap()
115            .progress_chars("=>-"));
116        pb.set_message(message.to_string());
117        pb
118    }
119
120    // New method for displaying cloud-themed progress
121    pub fn deploy_with_progress(&self, steps: u64) -> Result<()> {
122        let pb = self.create_progress_bar(steps, "Deploying to cloud");
123
124        for i in 0..steps {
125            pb.inc(1);
126
127            // Add different messages based on progress
128            match i {
129                1 => pb.set_message("Initializing containers...".to_string()),
130                3 => pb.set_message("Configuring network...".to_string()),
131                5 => pb.set_message("Launching services...".to_string()),
132                7 => pb.set_message("Almost there...".to_string()),
133                _ => {}
134            }
135
136            thread::sleep(Duration::from_millis(300));
137        }
138
139        pb.finish_with_message("Deployment complete!".to_string());
140        Ok(())
141    }
142}