feat(apple): Add button to show menuBar from FirstTimeView (#5505)

Fixes #5500 

Unfortunately showing the menubar menu _only_ on re-launch is
non-trivial due to the way "re-launches" are processed in macOS.

We can handle them with the `applicationDidBecomeActive` override in
`AppDelegate`, but then this will be triggered whenever we sign in, open
Settings, or open About window because we activate the app then as well
in order to bring the Window to the foreground.

There's no good to way to determine who asked us to activate either.

Instead, we show the Welcome window (FirstTimeView on macOS), and in
there is a new button to show the app menu to use as a fallback for
users who need an alternative way to open the menu with a busy menubar.


<img width="1012" alt="Screenshot 2024-06-23 at 5 14 57 PM"
src="https://github.com/firezone/firezone/assets/167144/1a7dde08-1e83-4dc8-9516-e0390f29c941">
This commit is contained in:
Jamil
2024-06-24 09:54:04 -07:00
committed by GitHub
parent d59b3764c7
commit 0993583fea
3 changed files with 27 additions and 8 deletions

View File

@@ -36,7 +36,10 @@ struct FirezoneApp: App {
"Welcome to Firezone",
id: AppViewModel.WindowDefinition.main.identifier
) {
AppView(model: appViewModel)
if let menuBar = appDelegate.menuBar {
// menuBar will be initialized by this point
AppView(model: appViewModel).environmentObject(menuBar)
}
}
.handlesExternalEvents(
matching: [AppViewModel.WindowDefinition.main.externalEventMatchString]
@@ -58,7 +61,7 @@ struct FirezoneApp: App {
#if os(macOS)
@MainActor
final class AppDelegate: NSObject, NSApplicationDelegate {
private var menuBar: MenuBar?
var menuBar: MenuBar?
public var store: Store?
func applicationDidFinishLaunching(_: Notification) {

View File

@@ -9,6 +9,8 @@ import SwiftUI
#if os(macOS)
struct FirstTimeView: View {
@EnvironmentObject var menuBar: MenuBar
var body: some View {
VStack(
alignment: .center,
@@ -21,17 +23,27 @@ struct FirstTimeView: View {
.padding(.horizontal, 10)
Spacer()
Text(
"You can sign in to Firezone by clicking on the Firezone icon in the macOS menu bar.\nYou may now close this window."
"You can sign in by clicking the Firezone icon in the macOS menu bar or clicking 'Open menu' below."
)
.font(.body)
.multilineTextAlignment(.center)
Spacer()
Button("Close this Window") {
AppViewModel.WindowDefinition.main.window()?.close()
HStack {
Button("Close this window") {
AppViewModel.WindowDefinition.main.window()?.close()
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
Button("Open menu") {
DispatchQueue.main.async {
menuBar.showMenu()
}
AppViewModel.WindowDefinition.main.window()?.close()
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
Spacer()
.frame(maxHeight: 20)
Text(

View File

@@ -16,7 +16,7 @@ import SwiftUI
@MainActor
// TODO: Refactor to MenuBarExtra for macOS 13+
// https://developer.apple.com/documentation/swiftui/menubarextra
public final class MenuBar: NSObject {
public final class MenuBar: NSObject, ObservableObject {
private var statusItem: NSStatusItem
private var resources: [Resource]?
private var cancellables: Set<AnyCancellable> = []
@@ -48,6 +48,10 @@ public final class MenuBar: NSObject {
setupObservers()
}
func showMenu() {
statusItem.button?.performClick(nil)
}
private func setupObservers() {
model.store.$status
.receive(on: DispatchQueue.main)