A new Apple-silicon app in viewer/macos (Swift, no dependencies, ~1 MB): one window showing a ProdDash dashboard in WebKit, and nothing else. It runs no server; it points at any ProdDash on the network. - Connections (name + address) in Settings; the add/edit sheet asks /api/modules whether ProdDash answers as you type. No port means 24500. - Two or more connections bring a slim tab bar of their names. In a window it floats over the dashboard and comes out while the pointer is on the title bar; it is not part of the title bar, because anything there makes WebKit push the page down. In full screen it is a titlebar accessory that comes down with the menu bar, and it flashes up after each switch. ⌃Tab / ⌃⇧Tab and ⌘1–9 switch from the keyboard. - Full screen, reopening in full screen if it quit there; window size and the selected tab are kept too. The dashboard's own full-screen button works as well. - Menus: View (Back, Forward, Reload Page, Enter Full Screen), Settings, Edit (copy/paste in the page's text fields), Window, Help (a guide that ships in the app). - Every installation keeps its own live web view. One that can't be reached says why and retries at 2, 4, 8, then every 15 s; a redirect off the installation is reported, not handed to the browser. JS alert, confirm and prompt show as sheets; links to other sites open in the browser. - General settings: open at login (SMAppService), keep the display awake while a dashboard is on screen (default on). build.sh signs with the Developer ID when one is installed and makes a notarised DMG with --notarize, as the launcher's does. It needs Xcode: with only the command line tools the macOS 27 SDK can't expand SwiftUI's @State. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
43 lines
1.6 KiB
Swift
43 lines
1.6 KiB
Swift
import AppKit
|
|
import WebKit
|
|
|
|
/// Help → ProdDash Viewer Help: the page that ships inside the app, so it
|
|
/// opens with no network and always matches this version.
|
|
final class HelpWindowController: NSWindowController, WKNavigationDelegate {
|
|
|
|
convenience init() {
|
|
let web = WKWebView()
|
|
let window = NSWindow(
|
|
contentRect: NSRect(x: 0, y: 0, width: 640, height: 720),
|
|
styleMask: [.titled, .closable, .miniaturizable, .resizable],
|
|
backing: .buffered, defer: false)
|
|
window.title = "ProdDash Viewer Help"
|
|
window.minSize = NSSize(width: 420, height: 360)
|
|
window.contentView = web
|
|
window.tabbingMode = .disallowed
|
|
window.isRestorable = false
|
|
window.center()
|
|
window.setFrameAutosaveName("ProdDashViewerHelp")
|
|
self.init(window: window)
|
|
web.navigationDelegate = self
|
|
if let page = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Help") {
|
|
web.loadFileURL(page, allowingReadAccessTo: page.deletingLastPathComponent())
|
|
}
|
|
}
|
|
|
|
func show() {
|
|
showWindow(nil)
|
|
window?.makeKeyAndOrderFront(nil)
|
|
}
|
|
|
|
/// The help page itself stays here; its links to the web open in the browser.
|
|
func webView(_ webView: WKWebView, decidePolicyFor action: WKNavigationAction,
|
|
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
|
guard let url = action.request.url, !url.isFileURL, url.scheme != "about" else {
|
|
return decisionHandler(.allow)
|
|
}
|
|
NSWorkspace.shared.open(url)
|
|
decisionHandler(.cancel)
|
|
}
|
|
}
|