oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1import AppKit
2import CallsKit
3import SwiftUI
4
5/// Offline visual fixtures of the shipping lobby. Only built into the test executable.
6///
7/// Every model reads its server from a throwaway defaults suite, so a
8/// fixture neither sees nor changes the setting of whoever runs it.
9@MainActor enum LobbySnapshots {
10 static func save(to directory: String) async throws {
11 NSApplication.shared.setActivationPolicy(.prohibited)
12 let folder = URL(fileURLWithPath: directory)
13 try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
14 let suite = "CallsInterop.LobbySnapshots"
15 guard let defaults = UserDefaults(suiteName: suite) else { return }
16 defaults.removePersistentDomain(forName: suite)
17 defer { defaults.removePersistentDomain(forName: suite) }
18 for scheme in [ColorScheme.light, .dark] {
19 for state in [
20 "welcome", "signin", "home", "ready", "error", "expired", "link-other", "visiting",
21 ] {
22 let model = CallsModel(defaults: defaults)
23 if state == "signin" {
24 model.authenticating = true
25 model.confirmationCode = "A1B2-C3D4"
26 model.signin = URL(string: "https://example.invalid")
27 }
28 if state == "home" {
29 model.signedIn = true
30 model.canStart = true
31 model.origin = "https://calls.oficina.works"
32 }
33 if state == "ready" {
34 model.signedIn = true
35 model.canStart = true
36 model.origin = "https://calls.oficina.works"
37 model.room = "team-catchup"
38 }
39 if state == "error" {
40 model.error = "Could not reach calls.oficina.works. Choose Sign in to try again."
41 }
42 if state == "expired" {
43 model.error = "Your sign-in to calls.oficina.works has ended. Choose Sign in to continue."
44 }
45 if state == "link-other" {
46 model.pendingLink = "https://calls.example.org/j/invitation"
47 }
48 if state == "visiting" {
49 model.signedIn = true
50 model.visiting = true
51 model.origin = "https://calls.example.org"
52 model.room = "abc123"
53 }
54 try await render(
55 CallsLobby(model: model), scheme: scheme, size: CGSize(width: 900, height: 720),
56 to: folder.appendingPathComponent("\(state)-\(name(scheme)).png"))
57 }
58 // The same signed-out home at iPhone width, with the Change button
59 // the phone's settings sheet is reached by.
60 try await render(
61 CallsLobby(model: CallsModel(defaults: defaults), openSettings: {}), scheme: scheme,
62 size: CGSize(width: 390, height: 780),
63 to: folder.appendingPathComponent("phone-welcome-\(name(scheme)).png"))
64 try await render(
65 GuestJoinView(model: CallsModel(defaults: defaults)) {}, scheme: scheme, size: nil,
66 to: folder.appendingPathComponent("guest-\(name(scheme)).png"))
67 try await render(
68 GuestJoinView(
69 model: CallsModel(defaults: defaults), link: "calls.example.org/settings", problem: true
70 ) {}, scheme: scheme, size: nil,
71 to: folder.appendingPathComponent("guest-invalid-\(name(scheme)).png"))
72 try await render(
73 ServerSettingsSheet(model: CallsModel(defaults: defaults)) {}, scheme: scheme,
74 size: CGSize(width: 390, height: 520),
75 to: folder.appendingPathComponent("phone-settings-\(name(scheme)).png"))
76 }
77 try await SettingsSnapshots.save(to: folder)
78 try await MiniWindowSnapshots.save(to: folder)
79 try await CallSnapshots.save(to: folder)
80 }
81
82 static func name(_ scheme: ColorScheme) -> String { scheme == .dark ? "dark" : "light" }
83
84 /// Draws a view off screen into a PNG. A nil size takes the view's own.
85 static func render(_ content: some View, scheme: ColorScheme, size: CGSize?, to file: URL)
86 async throws
87 {
88 let view = NSHostingView(
89 rootView: content.background(scheme == .dark ? Color(white: 0.12) : Color(white: 0.98))
90 .environment(\.colorScheme, scheme))
91 let frame = size ?? view.fittingSize
92 view.frame.size = frame
93 let window = NSWindow(
94 contentRect: NSRect(origin: CGPoint(x: -2000, y: -2000), size: frame),
95 styleMask: [.borderless], backing: .buffered, defer: false)
96 window.isReleasedWhenClosed = false
97 window.appearance = NSAppearance(named: scheme == .dark ? .darkAqua : .aqua)
98 window.contentView = view
99 window.orderFront(nil)
100 try await Task.sleep(for: .milliseconds(300))
101 view.layoutSubtreeIfNeeded()
102 guard let bitmap = view.bitmapImageRepForCachingDisplay(in: view.bounds) else {
103 throw CocoaError(.fileWriteUnknown)
104 }
105 view.cacheDisplay(in: view.bounds, to: bitmap)
106 guard let data = bitmap.representation(using: .png, properties: [:]) else {
107 throw CocoaError(.fileWriteUnknown)
108 }
109 try data.write(to: file)
110 window.close()
111 }
112}
113