# 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](../../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 ```bash ./build.sh # build/ProdDash Viewer.app ./build.sh --dmg # …and build/ProdDash-Viewer--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](../../launcher/macos/README.md#signing). 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`, `confirm` and `prompt` — 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.