-
-
Notifications
You must be signed in to change notification settings - Fork 125
Expand file tree
/
Copy pathAppPreferences.swift
More file actions
206 lines (178 loc) · 6.74 KB
/
Copy pathAppPreferences.swift
File metadata and controls
206 lines (178 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import Foundation
import AppKit
import SwiftUI
enum AppPreferences {
// MARK: - Keys
private static let appearanceKey = "bs_appAppearance"
private static let saveDirKey = "bs_saveDirectory"
private static let copyAfterSaveKey = "bs_copyAfterSave"
private static let playSoundKey = "bs_playSound"
private static let overlayPositionKey = "bs_overlayPosition"
private static let overlayDismissDelayKey = "bs_overlayDismissDelay"
private static let overlayNeverDismissKey = "bs_overlayNeverDismiss"
private static let exportFormatKey = "bs_exportFormat"
private static let exportQualityKey = "bs_exportQuality"
private static let selfTimerKey = "bs_selfTimerDelay"
private static let recordingFPSKey = "bs_recordingFPS"
private static let recordingShowCursorKey = "bs_recordingShowCursor"
private static let recordingCaptureAudioKey = "bs_recordingCaptureAudio"
private static let recordingOpenEditorKey = "bs_recordingOpenEditor"
// MARK: - Appearance
static var appearance: AppAppearance {
get {
guard let raw = UserDefaults.standard.string(forKey: appearanceKey),
let appearance = AppAppearance(rawValue: raw) else { return .system }
return appearance
}
set { UserDefaults.standard.set(newValue.rawValue, forKey: appearanceKey) }
}
@MainActor
static func applyAppearance() {
NSApp.appearance = appearance.nsAppearance
}
// MARK: - General
static var saveDirectory: String {
get { UserDefaults.standard.string(forKey: saveDirKey) ?? NSHomeDirectory() + "/Desktop" }
set { UserDefaults.standard.set(newValue, forKey: saveDirKey) }
}
static var copyAfterSave: Bool {
get { UserDefaults.standard.object(forKey: copyAfterSaveKey) as? Bool ?? true }
set { UserDefaults.standard.set(newValue, forKey: copyAfterSaveKey) }
}
static var playSound: Bool {
get { UserDefaults.standard.object(forKey: playSoundKey) as? Bool ?? true }
set { UserDefaults.standard.set(newValue, forKey: playSoundKey) }
}
// MARK: - Overlay
static var overlayPosition: OverlayPosition {
get {
guard let raw = UserDefaults.standard.string(forKey: overlayPositionKey),
let pos = OverlayPosition(rawValue: raw) else { return .bottomRight }
return pos
}
set { UserDefaults.standard.set(newValue.rawValue, forKey: overlayPositionKey) }
}
static var overlayDismissDelay: Double {
get {
let val = UserDefaults.standard.double(forKey: overlayDismissDelayKey)
return val > 0 ? val : 5.0
}
set { UserDefaults.standard.set(newValue, forKey: overlayDismissDelayKey) }
}
/// When true, preview overlay cards stay visible until manually closed
/// (no auto-dismiss timer).
static var overlayNeverDismiss: Bool {
get { UserDefaults.standard.object(forKey: overlayNeverDismissKey) as? Bool ?? false }
set { UserDefaults.standard.set(newValue, forKey: overlayNeverDismissKey) }
}
// MARK: - Export
static var exportFormat: ExportFormat {
get {
guard let raw = UserDefaults.standard.string(forKey: exportFormatKey),
let fmt = ExportFormat(rawValue: raw) else { return .png }
return fmt
}
set { UserDefaults.standard.set(newValue.rawValue, forKey: exportFormatKey) }
}
static var exportQuality: Double {
get {
let val = UserDefaults.standard.double(forKey: exportQualityKey)
return val > 0 ? val : 0.9
}
set { UserDefaults.standard.set(newValue, forKey: exportQualityKey) }
}
// MARK: - Self Timer
static var selfTimerDelay: SelfTimerDelay {
get {
let val = UserDefaults.standard.integer(forKey: selfTimerKey)
return SelfTimerDelay(rawValue: val) ?? .off
}
set { UserDefaults.standard.set(newValue.rawValue, forKey: selfTimerKey) }
}
// MARK: - Recording
static var recordingFPS: Int {
get {
let val = UserDefaults.standard.integer(forKey: recordingFPSKey)
return val > 0 ? val : 30
}
set { UserDefaults.standard.set(newValue, forKey: recordingFPSKey) }
}
static var recordingShowCursor: Bool {
get { UserDefaults.standard.object(forKey: recordingShowCursorKey) as? Bool ?? true }
set { UserDefaults.standard.set(newValue, forKey: recordingShowCursorKey) }
}
static var recordingCaptureAudio: Bool {
get { UserDefaults.standard.object(forKey: recordingCaptureAudioKey) as? Bool ?? false }
set { UserDefaults.standard.set(newValue, forKey: recordingCaptureAudioKey) }
}
static var recordingOpenEditor: Bool {
get { UserDefaults.standard.object(forKey: recordingOpenEditorKey) as? Bool ?? true }
set { UserDefaults.standard.set(newValue, forKey: recordingOpenEditorKey) }
}
// MARK: - Default Beautifier Config
static var defaultBeautifierConfig: BeautifierConfig {
get {
guard let data = UserDefaults.standard.data(forKey: "bs_defaultBeautifierConfig"),
let config = try? JSONDecoder().decode(BeautifierConfig.self, from: data)
else { return .default }
return config
}
set {
if let data = try? JSONEncoder().encode(newValue) {
UserDefaults.standard.set(data, forKey: "bs_defaultBeautifierConfig")
}
}
}
}
// MARK: - Enums
enum AppAppearance: String, CaseIterable, Identifiable {
case system
case light
case dark
var id: String { rawValue }
var label: String {
switch self {
case .system: return "System"
case .light: return "Light"
case .dark: return "Dark"
}
}
var nsAppearance: NSAppearance? {
switch self {
case .system: return nil
case .light: return NSAppearance(named: .aqua)
case .dark: return NSAppearance(named: .darkAqua)
}
}
}
enum OverlayPosition: String, CaseIterable, Codable {
case bottomRight = "bottomRight"
case bottomLeft = "bottomLeft"
}
enum ExportFormat: String, CaseIterable {
case png, jpeg
var utType: String {
switch self {
case .png: return "public.png"
case .jpeg: return "public.jpeg"
}
}
var fileExtension: String {
switch self {
case .png: return "png"
case .jpeg: return "jpg"
}
}
}
enum SelfTimerDelay: Int, CaseIterable {
case off = 0
case three = 3
case five = 5
case ten = 10
var label: String {
switch self {
case .off: return "Off"
default: return "\(rawValue)s"
}
}
}