Skip to content

Commit

Permalink
feat: The best splash screen (#46)
Browse files Browse the repository at this point in the history
- **feat: Add a kwekking splash screen while indexing**
- **Clippy**
  • Loading branch information
timonv authored Dec 20, 2024
1 parent e2f2d1d commit c1f2d8c
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 8 deletions.
88 changes: 88 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ clap = { version = "4.5.21", features = ["derive"] }
tera = "1.20.0"
lazy_static = "1.5.0"
rust-embed = { version = "8.5.0", features = ["debug-embed"] }
ratatui-splash-screen = "0.1.4"

[dev-dependencies]
test-log = { version = "0.2.16", features = ["trace"] }
Expand Down
Binary file added images/logo_term.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/logo_term_nobg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/logo_term_nobg_reduced.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 29 additions & 7 deletions src/frontend/app.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use anyhow::Result;
use indoc::indoc;
use std::io;
use std::time::Duration;
use strum::IntoEnumIterator as _;
use text::{ToLine as _, ToSpan};
use tui_logger::TuiWidgetState;
use tui_textarea::TextArea;
use uuid::Uuid;
Expand All @@ -22,6 +19,7 @@ use crate::{
chat::{Chat, ChatState},
chat_message::ChatMessage,
commands::Command,
frontend,
};

use super::{chat_mode, logs_mode, UIEvent, UserInputCommand};
Expand Down Expand Up @@ -64,6 +62,9 @@ pub struct App<'a> {

/// States when viewing logs
pub log_state: TuiWidgetState,

/// Commands that relate to boot, and not a chat
pub boot_uuid: Uuid,
}

#[derive(Debug, Clone, Copy, Default, PartialEq)]
Expand Down Expand Up @@ -132,6 +133,7 @@ impl Default for App<'_> {
.set_level_for_target("kwaak", log::LevelFilter::Info)
.set_level_for_target("swiftide", log::LevelFilter::Info),
selected_tab: 0,
boot_uuid: Uuid::new_v4(),
}
}
}
Expand Down Expand Up @@ -199,6 +201,9 @@ impl App<'_> {
}

fn add_chat_message(&mut self, message: ChatMessage) {
if message.uuid() == Some(self.boot_uuid) {
return;
}
let chat = self.find_chat_mut(message.uuid().unwrap_or(self.current_chat));
chat.add_message(message);
}
Expand All @@ -207,15 +212,27 @@ impl App<'_> {
pub async fn run<B: ratatui::backend::Backend>(
&mut self,
terminal: &mut Terminal<B>,
) -> io::Result<()> {
) -> Result<()> {
let handle = task::spawn(poll_ui_events(self.ui_tx.clone()));

let mut has_indexed_on_boot = false;
let mut splash = frontend::splash::Splash::default();

self.dispatch_command(&Command::IndexRepository {
uuid: self.boot_uuid,
});

loop {
// Draw the UI
terminal.draw(|f| {
let base_area = self.draw_base_ui(f);
if has_indexed_on_boot && splash.is_rendered() {
let base_area = self.draw_base_ui(f);

self.mode.ui(f, base_area, self);
self.mode.ui(f, base_area, self);
} else {
splash.render(f, "Indexing your code ...");
std::thread::sleep(Duration::from_millis(100));
}
})?;

if self.mode == AppMode::Quit {
Expand All @@ -235,7 +252,12 @@ impl App<'_> {
// Handle periodic tasks if necessary
}
UIEvent::CommandDone(uuid) => {
self.find_chat_mut(uuid).transition(ChatState::Ready);
if uuid == self.boot_uuid {
has_indexed_on_boot = true;
self.current_chat_mut().transition(ChatState::Ready);
} else {
self.find_chat_mut(uuid).transition(ChatState::Ready);
}
}
UIEvent::AgentActivity(uuid, activity) => {
self.find_chat_mut(uuid)
Expand Down
1 change: 0 additions & 1 deletion src/frontend/chat_mode/on_key.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crossterm::event::{KeyCode, KeyEvent};
use tui_textarea::TextArea;

use crate::{
chat_message::{ChatMessage, ChatMessageBuilder},
Expand Down
1 change: 1 addition & 0 deletions src/frontend/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod app;
mod splash;
mod ui_command;
mod ui_event;

Expand Down
67 changes: 67 additions & 0 deletions src/frontend/splash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use layout::Flex;
use ratatui::{
widgets::{Block, Padding},
Frame,
};
use ratatui_splash_screen::{SplashConfig, SplashScreen};

// use std::error::Error;
// use std::io::stdout;
// use std::time::Duration;
//
use ratatui::prelude::*;
// use ratatui_splash_screen::{SplashConfig, SplashScreen, SplashError};
//
static SPLASH_CONFIG: SplashConfig = SplashConfig {
image_data: include_bytes!("../../images/logo_term_nobg.png"),
sha256sum: None,
render_steps: 6,
use_colors: true,
};

pub struct Splash {
splash_screen: SplashScreen,
}

impl Default for Splash {
fn default() -> Self {
let splash_screen = SplashScreen::new(SPLASH_CONFIG).unwrap();
Splash { splash_screen }
}
}

// Splash renders in the center of the screen an image with a loading bar
// Image is 50x50 characters, below a line with the text "Indexing your code ..."
impl Splash {
pub fn render(&mut self, f: &mut Frame, status_text: &str) {
let splash_area = center(
f.area(),
Constraint::Percentage(48),
Constraint::Percentage(67),
);
let [image_area, text_area] =
Layout::vertical([Constraint::Fill(1), Constraint::Length(2)]).areas(splash_area);

f.render_widget(&mut self.splash_screen, image_area);

#[allow(clippy::cast_possible_truncation)]
let left_padding = (text_area.width - status_text.len() as u16) / 2;
let block = Block::default().padding(Padding::new(left_padding, 0, 1, 0));
let throbber = throbber_widgets_tui::Throbber::default().label(status_text);

f.render_widget(throbber, block.inner(text_area));
f.render_widget(block, text_area);
}

pub fn is_rendered(&self) -> bool {
self.splash_screen.is_rendered()
}
}

fn center(area: Rect, horizontal: Constraint, vertical: Constraint) -> Rect {
let [area] = Layout::horizontal([horizontal])
.flex(Flex::Center)
.areas(area);
let [area] = Layout::vertical([vertical]).flex(Flex::Center).areas(area);
area
}

0 comments on commit c1f2d8c

Please sign in to comment.