diff --git a/assets/brand/nova-brand.png b/assets/brand/nova-brand.png
new file mode 100644
index 0000000..0e8a8de
Binary files /dev/null and b/assets/brand/nova-brand.png differ
diff --git a/assets/brand/nova-brand.svg b/assets/brand/nova-brand.svg
new file mode 100644
index 0000000..43b5f05
--- /dev/null
+++ b/assets/brand/nova-brand.svg
@@ -0,0 +1,21 @@
+
diff --git a/src/ui/app_state/nova.rs b/src/ui/app_state/nova.rs
index 43a9f9b..f28ee3e 100644
--- a/src/ui/app_state/nova.rs
+++ b/src/ui/app_state/nova.rs
@@ -20,6 +20,7 @@ pub enum SettingsTab {
StatusBar,
Ai,
Raw,
+ About,
}
#[derive(Debug, Clone)]
diff --git a/src/ui/components/mod.rs b/src/ui/components/mod.rs
index c894bf7..a7cbba9 100644
--- a/src/ui/components/mod.rs
+++ b/src/ui/components/mod.rs
@@ -7,6 +7,7 @@ mod search_bar;
mod section_label;
mod setting_row;
mod settings;
+mod settings_about;
mod settings_ai;
mod settings_general;
mod settings_keybindings;
diff --git a/src/ui/components/settings.rs b/src/ui/components/settings.rs
index 6dd5878..bc0acab 100644
--- a/src/ui/components/settings.rs
+++ b/src/ui/components/settings.rs
@@ -15,7 +15,8 @@ use crate::ui::{
};
use super::{
- settings_ai, settings_general, settings_keybindings, settings_status_bar, settings_theme,
+ settings_about, settings_ai, settings_general, settings_keybindings, settings_status_bar,
+ settings_theme,
};
const SIDEBAR_WIDTH: f32 = 160.0;
@@ -133,68 +134,76 @@ fn modal_inner<'a>(
let body = row![
sidebar_nav(active_tab),
rule::vertical(1),
- container(
- scrollable(match active_tab {
- SettingsTab::General => settings_general::general_tab(settings, shell_input),
- SettingsTab::Theme => settings_theme::theme_tab(settings),
- SettingsTab::Keybindings =>
- settings_keybindings::keybindings_tab(settings, recording_index),
- SettingsTab::StatusBar => settings_status_bar::status_bar_tab(settings),
- SettingsTab::Ai => settings_ai::ai_tab(settings),
- SettingsTab::Raw => edit_raw_tab(raw_content),
- })
- .height(Length::Fill)
- .direction(scrollable::Direction::Vertical(
- scrollable::Scrollbar::new()
- .width(4)
- .margin(4)
- .scroller_width(4),
- ))
- .style(|_t, _status| scrollable::Style {
- container: container::Style::default(),
- vertical_rail: scrollable::Rail {
- background: None,
- border: Border::default(),
- scroller: scrollable::Scroller {
- background: Color {
- r: 0.5,
- g: 0.5,
- b: 0.5,
- a: 0.35,
- }
- .into(),
- border: Border {
- color: Color::TRANSPARENT,
- radius: Radius::new(4.0),
- width: 0.0,
+ if *active_tab == SettingsTab::About {
+ container(settings_about::about_tab())
+ .width(Length::Fill)
+ .height(Length::Fill)
+ } else {
+ container(
+ scrollable(match active_tab {
+ SettingsTab::General => settings_general::general_tab(settings, shell_input),
+ SettingsTab::Theme => settings_theme::theme_tab(settings),
+ SettingsTab::Keybindings => {
+ settings_keybindings::keybindings_tab(settings, recording_index)
+ }
+ SettingsTab::StatusBar => settings_status_bar::status_bar_tab(settings),
+ SettingsTab::Ai => settings_ai::ai_tab(settings),
+ SettingsTab::Raw => edit_raw_tab(raw_content),
+ SettingsTab::About => unreachable!(),
+ })
+ .height(Length::Fill)
+ .direction(scrollable::Direction::Vertical(
+ scrollable::Scrollbar::new()
+ .width(4)
+ .margin(4)
+ .scroller_width(4),
+ ))
+ .style(|_t, _status| scrollable::Style {
+ container: container::Style::default(),
+ vertical_rail: scrollable::Rail {
+ background: None,
+ border: Border::default(),
+ scroller: scrollable::Scroller {
+ background: Color {
+ r: 0.5,
+ g: 0.5,
+ b: 0.5,
+ a: 0.35,
+ }
+ .into(),
+ border: Border {
+ color: Color::TRANSPARENT,
+ radius: Radius::new(4.0),
+ width: 0.0,
+ },
+ },
+ },
+ horizontal_rail: scrollable::Rail {
+ background: None,
+ border: Border::default(),
+ scroller: scrollable::Scroller {
+ background: Color::TRANSPARENT.into(),
+ border: Border::default(),
},
},
- },
- horizontal_rail: scrollable::Rail {
- background: None,
- border: Border::default(),
- scroller: scrollable::Scroller {
+ gap: None,
+ auto_scroll: scrollable::AutoScroll {
background: Color::TRANSPARENT.into(),
border: Border::default(),
+ shadow: Shadow::default(),
+ icon: Color::TRANSPARENT,
},
- },
- gap: None,
- auto_scroll: scrollable::AutoScroll {
- background: Color::TRANSPARENT.into(),
- border: Border::default(),
- shadow: Shadow::default(),
- icon: Color::TRANSPARENT,
- },
- }),
- )
- .padding(Padding {
- top: 16.0,
- bottom: 16.0,
- left: 20.0,
- right: 16.0,
- })
- .width(Length::Fill)
- .height(Length::Fill),
+ }),
+ )
+ .padding(Padding {
+ top: 16.0,
+ bottom: 16.0,
+ left: 20.0,
+ right: 16.0,
+ })
+ .width(Length::Fill)
+ .height(Length::Fill)
+ },
]
.height(Length::Fill);
@@ -263,6 +272,7 @@ fn sidebar_nav<'a>(active_tab: &'a SettingsTab) -> Element<'a, Message> {
(SettingsTab::StatusBar, "Status Bar"),
(SettingsTab::Ai, "AI"),
(SettingsTab::Raw, "Raw"),
+ (SettingsTab::About, "About"),
];
let mut nav = column![].spacing(2).padding(Padding::from([8, 6]));
diff --git a/src/ui/components/settings_about.rs b/src/ui/components/settings_about.rs
new file mode 100644
index 0000000..eafc450
--- /dev/null
+++ b/src/ui/components/settings_about.rs
@@ -0,0 +1,35 @@
+use iced::{
+ ContentFit, Element, Length,
+ alignment::Horizontal,
+ widget::{column, container, svg, text},
+};
+
+use crate::ui::{app_state::Message, theme};
+
+const BRAND_SVG: &[u8] = include_bytes!("../../../assets/brand/nova-brand.svg");
+
+static BRAND_HANDLE: std::sync::LazyLock =
+ std::sync::LazyLock::new(|| svg::Handle::from_memory(BRAND_SVG));
+
+pub(super) fn about_tab<'a>() -> Element<'a, Message> {
+ let fg_muted = theme::color::runtime().foreground_muted;
+
+ container(
+ column![
+ svg(BRAND_HANDLE.clone())
+ .width(260)
+ .content_fit(ContentFit::Contain),
+ text(format!("v{}", env!("CARGO_PKG_VERSION")))
+ .font(theme::font::regular())
+ .size(12)
+ .color(fg_muted),
+ ]
+ .spacing(12)
+ .align_x(Horizontal::Center),
+ )
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .align_x(Horizontal::Center)
+ .align_y(iced::alignment::Vertical::Center)
+ .into()
+}