feat(onboarding): highlight voice wake, panel, and tools
This commit is contained in:
@@ -38,6 +38,7 @@ final class OnboardingController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct OnboardingView: View {
|
struct OnboardingView: View {
|
||||||
|
@Environment(\.openSettings) private var openSettings
|
||||||
@State private var currentPage = 0
|
@State private var currentPage = 0
|
||||||
@State private var isRequesting = false
|
@State private var isRequesting = false
|
||||||
@State private var installingCLI = false
|
@State private var installingCLI = false
|
||||||
@@ -473,10 +474,25 @@ struct OnboardingView: View {
|
|||||||
if you add a new user.
|
if you add a new user.
|
||||||
""",
|
""",
|
||||||
systemImage: "checkmark.seal")
|
systemImage: "checkmark.seal")
|
||||||
|
self.featureRow(
|
||||||
|
title: "Try Voice Wake",
|
||||||
|
subtitle: "Enable Voice Wake in Settings for hands-free commands with a live transcript overlay.",
|
||||||
|
systemImage: "waveform.circle")
|
||||||
|
self.featureRow(
|
||||||
|
title: "Use the panel + Canvas",
|
||||||
|
subtitle: "Open the menu bar panel for quick chat; the agent can show previews and richer visuals in Canvas.",
|
||||||
|
systemImage: "rectangle.inset.filled.and.person.filled")
|
||||||
self.featureRow(
|
self.featureRow(
|
||||||
title: "Test a notification",
|
title: "Test a notification",
|
||||||
subtitle: "Send a quick notify via the menu bar to confirm sounds and permissions.",
|
subtitle: "Send a quick notify via the menu bar to confirm sounds and permissions.",
|
||||||
systemImage: "bell.badge")
|
systemImage: "bell.badge")
|
||||||
|
self.featureActionRow(
|
||||||
|
title: "Give your agent more powers",
|
||||||
|
subtitle: "Install optional tools (Peekaboo, oracle, camsnap, …) from Settings → Tools.",
|
||||||
|
systemImage: "wrench.and.screwdriver")
|
||||||
|
{
|
||||||
|
self.openSettings(tab: .tools)
|
||||||
|
}
|
||||||
Toggle("Launch at login", isOn: self.$state.launchAtLogin)
|
Toggle("Launch at login", isOn: self.$state.launchAtLogin)
|
||||||
.onChange(of: self.state.launchAtLogin) { _, newValue in
|
.onChange(of: self.state.launchAtLogin) { _, newValue in
|
||||||
AppStateStore.updateLaunchAtLogin(enabled: newValue)
|
AppStateStore.updateLaunchAtLogin(enabled: newValue)
|
||||||
@@ -485,6 +501,12 @@ struct OnboardingView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func openSettings(tab: SettingsTab) {
|
||||||
|
SettingsTabRouter.request(tab)
|
||||||
|
self.openSettings()
|
||||||
|
NotificationCenter.default.post(name: .clawdisSelectSettingsTab, object: tab)
|
||||||
|
}
|
||||||
|
|
||||||
private var navigationBar: some View {
|
private var navigationBar: some View {
|
||||||
HStack(spacing: 20) {
|
HStack(spacing: 20) {
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .leading) {
|
||||||
@@ -577,6 +599,30 @@ struct OnboardingView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func featureActionRow(
|
||||||
|
title: String,
|
||||||
|
subtitle: String,
|
||||||
|
systemImage: String,
|
||||||
|
action: @escaping () -> Void) -> some View
|
||||||
|
{
|
||||||
|
HStack(alignment: .top, spacing: 12) {
|
||||||
|
Image(systemName: systemImage)
|
||||||
|
.font(.title3.weight(.semibold))
|
||||||
|
.foregroundStyle(Color.accentColor)
|
||||||
|
.frame(width: 26)
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
Text(title).font(.headline)
|
||||||
|
Text(subtitle)
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
Button("Open Settings → Tools", action: action)
|
||||||
|
.buttonStyle(.link)
|
||||||
|
.padding(.top, 2)
|
||||||
|
}
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func handleBack() {
|
private func handleBack() {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
self.currentPage = max(0, self.currentPage - 1)
|
self.currentPage = max(0, self.currentPage - 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user