oficina / meet Public

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

Plain git — no account needed to clone.

Download

Download this file

1#if os(macOS)
2 import SwiftUI
3
4 /// Calls → Settings…. Sections rather than tabs: there are a few things
5 /// worth choosing, and the next preference belongs beside them.
6 public struct CallsSettingsView: View {
7 @ObservedObject private var model: CallsModel
8 @AppStorage(MiniWindowPreferences.enabledKey) private var miniWindow =
9 MiniWindowPreferences.defaultEnabled
10 @AppStorage(MiniWindowPreferences.cornerKey) private var corner =
11 MiniWindowPreferences.defaultCorner
12 @AppStorage(MiniWindowPreferences.placementKey) private var placement =
13 MiniWindowPreferences.defaultPlacement
14 @AppStorage(MiniWindowPreferences.positionsKey) private var positions: String?
15 @AppStorage(CallLayoutStyle.key) private var callLayout = CallLayoutStyle.defaultStyle
16
17 public init(model: CallsModel) { self.model = model }
18
19 public var body: some View {
20 Form {
21 Section {
22 Picker(selection: $callLayout) {
23 ForEach(CallLayoutStyle.allCases) { style in
24 Text(style.title).tag(style)
25 }
26 } label: {
27 Text("Call layout")
28 Text(
29 callLayout == .fullWindow
30 ? "The call fills the window. Move the pointer over it to show the controls."
31 : "The call sits above a row of controls that are always showing."
32 )
33 }
34 .accessibilityIdentifier("callLayout")
35 Toggle(isOn: $miniWindow) {
36 Text("Show a mini window when you switch to another app")
37 Text(
38 "During a call, a small window of the call stays on top of other apps. The full call returns when you come back to Calls."
39 )
40 }
41 Picker(selection: $placement) {
42 ForEach(MiniWindowPlacement.allCases) { placement in
43 Text(placement.title).tag(placement)
44 }
45 } label: {
46 Text("Mini window placement")
47 Text(placementNote)
48 }
49 .disabled(!miniWindow)
50 Picker(selection: $corner) {
51 ForEach(MiniWindowCorner.allCases) { corner in
52 Text(corner.title).tag(corner)
53 }
54 } label: {
55 Text("Mini window position")
56 Text(
57 placement == .corners
58 ? "You can also drag the mini window to another corner, and resize it from its edges."
59 : "Where it starts. Choosing a corner here moves it back into that corner."
60 )
61 }
62 .disabled(!miniWindow)
63 .onChange(of: corner) {
64 // A corner chosen here is asked for: whatever position the
65 // window was left at, on any display, gives way to it.
66 positions = nil
67 }
68 } header: {
69 Text("During a call")
70 }
71 ServerSettingsSection(model: model)
72 QualityReportsSection()
73 if let automaticUpdates {
74 Section {
75 Toggle(isOn: automaticUpdates) {
76 Text("Update Calls automatically")
77 Text(
78 "Updates download in the background and install when you quit Calls, never during a call."
79 )
80 }
81 .accessibilityIdentifier("automaticUpdates")
82 } header: {
83 Text("Updates")
84 }
85 }
86 }
87 .formStyle(.grouped)
88 .frame(width: 480)
89 .fixedSize(horizontal: false, vertical: true)
90 .tint(CallsAppearance.accent)
91 }
92
93 /// Nil where the build cannot update itself: development builds, and iPhone.
94 private var automaticUpdates: Binding<Bool>?
95
96 /// Adds the automatic-update switch, from the Mac app that owns the updater.
97 public init(model: CallsModel, automaticUpdates: Binding<Bool>?) {
98 self.model = model
99 self.automaticUpdates = automaticUpdates
100 }
101
102 private var placementNote: String {
103 switch placement {
104 case .corners:
105 "A dragged mini window settles in the nearest corner. Hold ⌥ Option while dragging to leave it exactly where you drop it, for this call."
106 case .anywhere:
107 "The mini window stays exactly where you leave it, remembered for each display."
108 }
109 }
110 }
111#endif
112