Skip to content

Commit 40f6fcb

Browse files
vforshVladislav ForshDimillian
authored
feat(settings): add About section with build metadata (#490)
Co-authored-by: Vladislav Forsh <forsh@eot.games> Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
1 parent b38a505 commit 40f6fcb

11 files changed

Lines changed: 141 additions & 0 deletions

File tree

src-tauri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ pub fn run() {
277277
dictation::dictation_cancel,
278278
local_usage::local_usage_snapshot,
279279
notifications::is_macos_debug_build,
280+
notifications::app_build_type,
280281
notifications::send_notification_fallback,
281282
tailscale::tailscale_status,
282283
tailscale::tailscale_daemon_command_preview,

src-tauri/src/notifications.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ pub(crate) async fn is_macos_debug_build() -> bool {
66
cfg!(all(target_os = "macos", debug_assertions))
77
}
88

9+
#[tauri::command]
10+
pub(crate) async fn app_build_type() -> String {
11+
if cfg!(debug_assertions) {
12+
"debug".to_string()
13+
} else {
14+
"release".to_string()
15+
}
16+
}
17+
918
/// macOS dev-mode fallback for system notifications.
1019
///
1120
/// In `tauri dev` (debug assertions enabled), the app is typically run as a

src/features/app/hooks/useSettingsModalState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useCallback, useState } from "react";
33
export type SettingsSection =
44
| "projects"
55
| "display"
6+
| "about"
67
| "dictation"
78
| "shortcuts"
89
| "open-apps"

src/features/settings/components/SettingsNav.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ExternalLink from "lucide-react/dist/esm/icons/external-link";
1010
import Layers from "lucide-react/dist/esm/icons/layers";
1111
import ServerCog from "lucide-react/dist/esm/icons/server-cog";
1212
import Bot from "lucide-react/dist/esm/icons/bot";
13+
import Info from "lucide-react/dist/esm/icons/info";
1314
import { PanelNavItem, PanelNavList } from "@/features/design-system/components/panel/PanelPrimitives";
1415
import type { CodexSection } from "./settingsTypes";
1516

@@ -135,6 +136,15 @@ export function SettingsNav({
135136
>
136137
Features
137138
</PanelNavItem>
139+
<PanelNavItem
140+
className="settings-nav"
141+
icon={<Info aria-hidden />}
142+
active={activeSection === "about"}
143+
showDisclosure={showDisclosure}
144+
onClick={() => onSelectSection("about")}
145+
>
146+
About
147+
</PanelNavItem>
138148
</PanelNavList>
139149
</aside>
140150
);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { useEffect, useState } from "react";
2+
import { getAppBuildType, type AppBuildType } from "@services/tauri";
3+
4+
export function SettingsAboutSection() {
5+
const [appBuildType, setAppBuildType] = useState<AppBuildType | "unknown">("unknown");
6+
7+
useEffect(() => {
8+
let active = true;
9+
const loadBuildType = async () => {
10+
try {
11+
const value = await getAppBuildType();
12+
if (active) {
13+
setAppBuildType(value);
14+
}
15+
} catch {
16+
if (active) {
17+
setAppBuildType("unknown");
18+
}
19+
}
20+
};
21+
void loadBuildType();
22+
return () => {
23+
active = false;
24+
};
25+
}, []);
26+
27+
const buildDateValue = __APP_BUILD_DATE__.trim();
28+
const parsedBuildDate = Date.parse(buildDateValue);
29+
const buildDateLabel = Number.isNaN(parsedBuildDate)
30+
? buildDateValue || "unknown"
31+
: new Date(parsedBuildDate).toLocaleString();
32+
33+
return (
34+
<section className="settings-section">
35+
<div className="settings-field">
36+
<div className="settings-help">
37+
Version: <code>{__APP_VERSION__}</code>
38+
</div>
39+
<div className="settings-help">
40+
Build type: <code>{appBuildType}</code>
41+
</div>
42+
<div className="settings-help">
43+
Branch: <code>{__APP_GIT_BRANCH__ || "unknown"}</code>
44+
</div>
45+
<div className="settings-help">
46+
Commit: <code>{__APP_COMMIT_HASH__ || "unknown"}</code>
47+
</div>
48+
<div className="settings-help">
49+
Build date: <code>{buildDateLabel}</code>
50+
</div>
51+
</div>
52+
</section>
53+
);
54+
}

src/features/settings/components/sections/SettingsSectionContainers.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { SettingsProjectsSection } from "./SettingsProjectsSection";
1010
import { SettingsServerSection } from "./SettingsServerSection";
1111
import { SettingsShortcutsSection } from "./SettingsShortcutsSection";
1212
import { SettingsAgentsSection } from "./SettingsAgentsSection";
13+
import { SettingsAboutSection } from "./SettingsAboutSection";
1314
import type { CodexSection } from "@settings/components/settingsTypes";
1415
import type { SettingsViewOrchestration } from "@settings/hooks/useSettingsViewOrchestration";
1516

@@ -31,6 +32,9 @@ export function SettingsSectionContainers({
3132
if (activeSection === "display") {
3233
return <SettingsDisplaySection {...orchestration.displaySectionProps} />;
3334
}
35+
if (activeSection === "about") {
36+
return <SettingsAboutSection />;
37+
}
3438
if (activeSection === "composer") {
3539
return <SettingsComposerSection {...orchestration.composerSectionProps} />;
3640
}

src/features/settings/components/settingsTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ type SettingsSection =
44
| "projects"
55
| "environments"
66
| "display"
7+
| "about"
78
| "composer"
89
| "dictation"
910
| "shortcuts"

src/features/settings/components/settingsViewConstants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export const SETTINGS_SECTION_LABELS: Record<CodexSection, string> = {
7777
projects: "Projects",
7878
environments: "Environments",
7979
display: "Display & Sound",
80+
about: "About",
8081
composer: "Composer",
8182
dictation: "Dictation",
8283
shortcuts: "Shortcuts",

src/services/tauri.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,12 @@ export async function generateAgentDescription(
10821082
return invoke("generate_agent_description", { workspaceId, description });
10831083
}
10841084

1085+
export type AppBuildType = "debug" | "release";
1086+
1087+
export async function getAppBuildType(): Promise<AppBuildType> {
1088+
return invoke<AppBuildType>("app_build_type");
1089+
}
1090+
10851091
export async function sendNotification(
10861092
title: string,
10871093
body: string,

src/vite-env.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
/// <reference types="vite/client" />
22

33
declare const __APP_VERSION__: string;
4+
declare const __APP_COMMIT_HASH__: string;
5+
declare const __APP_BUILD_DATE__: string;
6+
declare const __APP_GIT_BRANCH__: string;

0 commit comments

Comments
 (0)