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>
ProdDash Viewer for macOS
A Mac app whose only job is to show ProdDash. It opens one installation's dashboard in its own window — or several, with a slim tab bar to switch between them — and does nothing else: no address bar, no bookmarks, no browser to wander off in. It is for the screens that just show a dashboard: a booth display, a stage-manager's laptop, a second Mac watching the other campus.
It runs no server. ProdDash itself is installed with the menu-bar app in launcher/macos; the Viewer points at that, or at any other ProdDash on the network.
Apple silicon, macOS 13 or newer. Native Swift (AppKit with a little SwiftUI, WebKit for the page), no dependencies, about 1 MB.
Build
./build.sh # build/ProdDash Viewer.app
./build.sh --dmg # …and build/ProdDash-Viewer-<version>-arm64.dmg
./build.sh --install # …and copy it to /Applications
./build.sh --run # …and open it
./build.sh --notarize # with --dmg: notarise and staple (Developer ID)
Needs Xcode, selected with xcode-select — with only the command line
tools, the macOS 27 SDK can't expand SwiftUI's @State macro and the
compile fails. Signing and notarising work exactly as
for ProdDash's own app — a Developer ID certificate when one is installed,
ad-hoc otherwise, and the same proddash notarytool profile; see
launcher/macos/README.md. The
Viewer keeps its own version number (VERSION in build.sh), since it works
with any ProdDash rather than shipping with one.
The icon is Resources/AppIcon.png, drawn by Resources/make-icon.swift —
ProdDash's tile mark on a display, so the two apps tell apart in Finder.
Run swift Resources/make-icon.swift Resources/AppIcon.png to redraw it.
Using it
Settings… (⌘,) → Connections → +: a name (what the tab says) and
the address you open ProdDash at in a browser, such as 10.3.11.152:24500.
Without a port, ProdDash's 24500 is assumed; a path is kept, so an address
can open a particular page. The sheet asks the address whether ProdDash is
answering as you type, but saves either way — the installation may simply be
switched off right now. Double-click a connection to change it, drag to
reorder the tabs.
With two or more connections the tab bar appears. In a window it floats over the top of the dashboard, comes out while the pointer is on the title bar and tucks away after; in full screen it comes down with the menu bar, and shows for a moment after each switch. ⌃Tab / ⌃⇧Tab and ⌘1…⌘9 switch from the keyboard. A tab marked ⚠︎ is an installation that isn't answering.
The menus are short on purpose: View has Back (⌘[), Forward (⌘]), Reload Page (⌘R) and Enter Full Screen; the rest is what every Mac app has. Edit is there because without it Copy and Paste do nothing in the dashboard's and the admin page's text fields. Help opens the guide that ships in the app.
Settings → General: Open at login, and Keep the display awake (on by default) — while a dashboard is on screen, the display doesn't dim or sleep. Minimised, hidden or covered, it lets go.
How it behaves
- Every dashboard stays live. Each connection has its own web view, kept running behind the one on screen, so switching is instant and nothing has to reconnect.
- The page never jumps. In a window the tab bar is an overlay rather than part of the title bar: anything in the title bar makes WebKit push the whole page down to clear it, and a dashboard re-flowing every time the bar came and went would be worse than no bar. In full screen it is a title bar accessory — there the title bar lives in a window of its own, and the page stays put.
- It comes back by itself. An installation that can't be reached shows why (nothing answering, can't be found, no network — including macOS withholding Local Network access) and is retried at 2, 4, 8 and then every 15 seconds. Once a dashboard has loaded, ProdDash's own service worker and reconnect logic carry it through a server restart.
- It comes back as it was left. The window's size and place, the tab that was showing, and full screen: quit in full screen and it reopens in full screen — so a booth Mac set to log in and open the Viewer at login returns to the dashboard on its own after a restart.
- It stays on ProdDash. Links to the installation's own pages open in
the window; links anywhere else (a Planning Center item, the release notes)
open in the default browser, as do downloads. The page's
alert,confirmandprompt— the admin page confirms before deleting a layout, Band Lineup prompts for names — show as sheets titled with the installation's name. - The dashboard's own full-screen button works, in addition to the window's: it fills the screen with the dashboard alone; Esc leaves.
- Closing the window quits the app, as with System Settings — there is only ever the one window.
- Safari's Develop menu can inspect a dashboard running in the Viewer.
Files
Sources/
main.swift NSApplication, nothing else
AppDelegate.swift lifecycle and the menus
ViewerWindowController.swift the window: pages, tab bar overlay/accessory,
full screen, keyboard switching, display awake
DashboardPage.swift one connection's web view, status view, retry,
navigation policy, JavaScript dialogs
TabBar.swift the tabs (SwiftUI), shared by overlay and accessory
Connections.swift Connection, address rules, the store, the probe
ViewerSettings.swift preferences and the login item
SettingsWindowController.swift Settings: Connections and General
HelpWindowController.swift Help → ProdDash Viewer Help
Resources/
Info.plist bundle id org.waterschurch.proddash.viewer
Help/index.html the guide shown by the Help menu
AppIcon.png, make-icon.swift the icon and what draws it
Preferences live in ~/Library/Preferences/org.waterschurch.proddash.viewer.plist
(connections, the selected tab, full screen, keep awake); the web views'
storage — each dashboard's own per-browser settings — in WebKit's default
store for the app.