mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
Add Help menu to menu bar with website and issue links
- Add Help submenu with links to website and GitHub issues - Include Check for Updates functionality (using Sparkle stub) - Display app version (0.1.3) in Help menu - Move About option from main menu to Help submenu - Update About description to "Turn any browser into your Mac's terminal."
This commit is contained in:
parent
9cbda0d4eb
commit
520cf9641d
2 changed files with 95 additions and 12 deletions
|
|
@ -51,7 +51,7 @@ struct AboutView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private var descriptionSection: some View {
|
private var descriptionSection: some View {
|
||||||
Text("Connect to AI providers with a unified interface")
|
Text("Turn any browser into your Mac's terminal.")
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
/// Main menu bar view displaying session status and app controls
|
||||||
struct MenuBarView: View {
|
struct MenuBarView: View {
|
||||||
@Environment(SessionMonitor.self) var sessionMonitor
|
@Environment(SessionMonitor.self) var sessionMonitor
|
||||||
@AppStorage("showInDock") private var showInDock = false
|
@AppStorage("showInDock") private var showInDock = false
|
||||||
|
@State private var showHelpMenu = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
|
@ -28,6 +30,23 @@ struct MenuBarView: View {
|
||||||
Divider()
|
Divider()
|
||||||
.padding(.vertical, 4)
|
.padding(.vertical, 4)
|
||||||
|
|
||||||
|
// Help menu
|
||||||
|
Button(action: {
|
||||||
|
showHelpMenu.toggle()
|
||||||
|
}) {
|
||||||
|
HStack {
|
||||||
|
Label("Help", systemImage: "questionmark.circle")
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "chevron.right")
|
||||||
|
.font(.system(size: 10))
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttonStyle(MenuButtonStyle())
|
||||||
|
.popover(isPresented: $showHelpMenu, arrowEdge: .trailing) {
|
||||||
|
HelpMenuView(showAboutInSettings: showAboutInSettings)
|
||||||
|
}
|
||||||
|
|
||||||
// Settings button
|
// Settings button
|
||||||
Button(action: {
|
Button(action: {
|
||||||
NSApp.openSettings()
|
NSApp.openSettings()
|
||||||
|
|
@ -38,17 +57,6 @@ struct MenuBarView: View {
|
||||||
.buttonStyle(MenuButtonStyle())
|
.buttonStyle(MenuButtonStyle())
|
||||||
.keyboardShortcut(",", modifiers: .command)
|
.keyboardShortcut(",", modifiers: .command)
|
||||||
|
|
||||||
Divider()
|
|
||||||
.padding(.vertical, 4)
|
|
||||||
|
|
||||||
// About button
|
|
||||||
Button(action: {
|
|
||||||
showAboutInSettings()
|
|
||||||
}) {
|
|
||||||
Label("About VibeTunnel", systemImage: "info.circle")
|
|
||||||
}
|
|
||||||
.buttonStyle(MenuButtonStyle())
|
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
.padding(.vertical, 4)
|
.padding(.vertical, 4)
|
||||||
|
|
||||||
|
|
@ -67,6 +75,7 @@ struct MenuBarView: View {
|
||||||
|
|
||||||
// MARK: - Session Count View
|
// MARK: - Session Count View
|
||||||
|
|
||||||
|
/// Displays the count of active SSH sessions
|
||||||
struct SessionCountView: View {
|
struct SessionCountView: View {
|
||||||
let count: Int
|
let count: Int
|
||||||
|
|
||||||
|
|
@ -91,6 +100,7 @@ struct SessionCountView: View {
|
||||||
|
|
||||||
// MARK: - Session List View
|
// MARK: - Session List View
|
||||||
|
|
||||||
|
/// Lists active SSH sessions with truncation for large lists
|
||||||
struct SessionListView: View {
|
struct SessionListView: View {
|
||||||
let sessions: [String: SessionMonitor.SessionInfo]
|
let sessions: [String: SessionMonitor.SessionInfo]
|
||||||
|
|
||||||
|
|
@ -119,6 +129,7 @@ struct SessionListView: View {
|
||||||
|
|
||||||
// MARK: - Session Row View
|
// MARK: - Session Row View
|
||||||
|
|
||||||
|
/// Individual row displaying session information
|
||||||
struct SessionRowView: View {
|
struct SessionRowView: View {
|
||||||
let session: (key: String, value: SessionMonitor.SessionInfo)
|
let session: (key: String, value: SessionMonitor.SessionInfo)
|
||||||
|
|
||||||
|
|
@ -139,6 +150,7 @@ struct SessionRowView: View {
|
||||||
|
|
||||||
// MARK: - Menu Button Style
|
// MARK: - Menu Button Style
|
||||||
|
|
||||||
|
/// Custom button style for menu items with hover effects
|
||||||
struct MenuButtonStyle: ButtonStyle {
|
struct MenuButtonStyle: ButtonStyle {
|
||||||
@State private var isHovered = false
|
@State private var isHovered = false
|
||||||
|
|
||||||
|
|
@ -158,6 +170,77 @@ struct MenuButtonStyle: ButtonStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Help Menu View
|
||||||
|
|
||||||
|
/// Help menu with links and app information
|
||||||
|
struct HelpMenuView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
let showAboutInSettings: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
// Website
|
||||||
|
Button(action: {
|
||||||
|
dismiss()
|
||||||
|
if let url = URL(string: "http://vibetunnel.sh") {
|
||||||
|
NSWorkspace.shared.open(url)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Label("Website", systemImage: "globe")
|
||||||
|
}
|
||||||
|
.buttonStyle(MenuButtonStyle())
|
||||||
|
|
||||||
|
// Report Issue
|
||||||
|
Button(action: {
|
||||||
|
dismiss()
|
||||||
|
if let url = URL(string: "https://github.com/amantus-ai/vibetunnel/issues") {
|
||||||
|
NSWorkspace.shared.open(url)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Label("Report Issue", systemImage: "exclamationmark.triangle")
|
||||||
|
}
|
||||||
|
.buttonStyle(MenuButtonStyle())
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
|
||||||
|
// Check for Updates
|
||||||
|
Button(action: {
|
||||||
|
dismiss()
|
||||||
|
SparkleUpdaterManager.shared.checkForUpdates()
|
||||||
|
}) {
|
||||||
|
Label("Check for Updates…", systemImage: "arrow.down.circle")
|
||||||
|
}
|
||||||
|
.buttonStyle(MenuButtonStyle())
|
||||||
|
|
||||||
|
// Version
|
||||||
|
HStack {
|
||||||
|
Text("Version \(appVersion)")
|
||||||
|
.font(.system(size: 13))
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 12)
|
||||||
|
.padding(.vertical, 6)
|
||||||
|
|
||||||
|
// About
|
||||||
|
Button(action: {
|
||||||
|
dismiss()
|
||||||
|
showAboutInSettings()
|
||||||
|
}) {
|
||||||
|
Label("About VibeTunnel", systemImage: "info.circle")
|
||||||
|
}
|
||||||
|
.buttonStyle(MenuButtonStyle())
|
||||||
|
}
|
||||||
|
.frame(minWidth: 200)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var appVersion: String {
|
||||||
|
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Helper Functions
|
// MARK: - Helper Functions
|
||||||
|
|
||||||
/// Shows the About section in the Settings window
|
/// Shows the About section in the Settings window
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue