general: semi-type masturbation
This commit is contained in:
22
Gaze/Data/structs.swift
Normal file
22
Gaze/Data/structs.swift
Normal file
@@ -0,0 +1,22 @@
|
||||
struct Range: Codable {
|
||||
var bounds: ClosedRange<Int>
|
||||
var step: Int
|
||||
}
|
||||
struct RangeChoice: Equatable {
|
||||
var val: Int?
|
||||
let range: Range?
|
||||
|
||||
static func == (lhs: RangeChoice, rhs: RangeChoice) -> Bool {
|
||||
lhs.val == rhs.val && lhs.range?.bounds.lowerBound == rhs.range?.bounds.lowerBound
|
||||
&& lhs.range?.bounds.upperBound == rhs.range?.bounds.upperBound
|
||||
}
|
||||
|
||||
init(val: Int? = nil, range: Range? = nil) {
|
||||
self.val = val
|
||||
self.range = range
|
||||
}
|
||||
|
||||
var isNil: Bool {
|
||||
return val == nil || range == nil
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,44 @@
|
||||
import SwiftUI
|
||||
|
||||
struct SliderSection: View {
|
||||
@Binding var intervalMinutes: Int
|
||||
@Binding var countdownSeconds: Int
|
||||
@Binding var intervalSettings: RangeChoice
|
||||
@Binding var countdownSettings: RangeChoice
|
||||
@Binding var enabled: Bool
|
||||
|
||||
let intervalRange: ClosedRange<Int>
|
||||
let countdownRange: ClosedRange<Int>?
|
||||
let type: String
|
||||
let previewFunc: () -> Void
|
||||
let reminderText: String
|
||||
|
||||
init(
|
||||
intervalMinutes: Binding<Int>,
|
||||
countdownSeconds: Binding<Int>,
|
||||
intervalRange: ClosedRange<Int>,
|
||||
countdownRange: ClosedRange<Int>? = nil,
|
||||
intervalSettings: Binding<RangeChoice>,
|
||||
countdownSettings: Binding<RangeChoice>?,
|
||||
enabled: Binding<Bool>,
|
||||
type: String,
|
||||
reminderText: String,
|
||||
previewFunc: @escaping () -> Void
|
||||
) {
|
||||
self._intervalMinutes = intervalMinutes
|
||||
self._countdownSeconds = countdownSeconds
|
||||
self.intervalRange = intervalRange
|
||||
self.countdownRange = countdownRange
|
||||
self._intervalSettings = intervalSettings
|
||||
self._countdownSettings = countdownSettings ?? .constant(RangeChoice(val: nil, range: nil))
|
||||
self._enabled = enabled
|
||||
self.type = type
|
||||
self.reminderText = reminderText
|
||||
self.previewFunc = previewFunc
|
||||
}
|
||||
|
||||
var reminderText: String {
|
||||
guard enabled else {
|
||||
return "\(type) reminders are currently disabled."
|
||||
}
|
||||
if countdownSettings.isNil && intervalSettings.isNil {
|
||||
return "You will be reminded every \(intervalSettings.val) minutes"
|
||||
}
|
||||
return
|
||||
"You will be \(countdownSettings.isNil ? "subtly" : "") reminded every \(intervalSettings.val) minutes for \(countdownSettings.val!) seconds"
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
Toggle("Enable \(type.titleCase) Reminders", isOn: $enabled)
|
||||
.font(.headline)
|
||||
|
||||
if enabled {
|
||||
if enabled && !intervalSettings.isNil {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
Text("Remind me every:")
|
||||
.font(.subheadline)
|
||||
@@ -44,29 +46,34 @@ struct SliderSection: View {
|
||||
HStack {
|
||||
Slider(
|
||||
value: Binding(
|
||||
get: { Double(intervalMinutes) },
|
||||
set: { intervalMinutes = Int($0) }
|
||||
get: { Double(intervalSettings.val ?? 0) },
|
||||
set: { intervalSettings.val = Int($0) }
|
||||
),
|
||||
in:
|
||||
Double(intervalRange.lowerBound)...Double(intervalRange.upperBound),
|
||||
Double(
|
||||
intervalSettings.range.bounds.lowerBound)...Double(
|
||||
intervalSettings.range.bounds.upperBound),
|
||||
step: 5.0)
|
||||
Text("\(intervalMinutes) min")
|
||||
Text("\(intervalSettings.val) min")
|
||||
.frame(width: 60, alignment: .trailing)
|
||||
.monospacedDigit()
|
||||
}
|
||||
|
||||
if let range = countdownRange {
|
||||
if let range = countdownSettings.range {
|
||||
Text("Look away for:")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
HStack {
|
||||
Slider(
|
||||
value: Binding(
|
||||
get: { Double(countdownSeconds) },
|
||||
set: { countdownSeconds = Int($0) }
|
||||
), in: Double(range.lowerBound)...Double(range.upperBound),
|
||||
get: { Double(countdownSettings.seconds ?? 0) },
|
||||
set: { countdownSettings.seconds = Int($0) }
|
||||
),
|
||||
in:
|
||||
Double(
|
||||
range.bounds.lowerBound)...Double(range.bounds.upperBound),
|
||||
step: 5.0)
|
||||
Text("\(countdownSeconds) sec")
|
||||
Text("\(countdownSettings.seconds ?? 0) sec")
|
||||
.frame(width: 60, alignment: .trailing)
|
||||
.monospacedDigit()
|
||||
}
|
||||
@@ -77,6 +84,7 @@ struct SliderSection: View {
|
||||
.glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
|
||||
|
||||
if enabled {
|
||||
|
||||
Text(
|
||||
reminderText
|
||||
)
|
||||
@@ -111,3 +119,4 @@ struct SliderSection: View {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ import SwiftUI
|
||||
|
||||
struct LookAwaySetupView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var intervalMinutes: Int
|
||||
@Binding var countdownSeconds: Int
|
||||
@Binding var intervalSettings: RangeChoice
|
||||
@Binding var countdownSettings: RangeChoice
|
||||
@State private var previewWindowController: NSWindowController?
|
||||
|
||||
var body: some View {
|
||||
@@ -62,17 +62,12 @@ struct LookAwaySetupView: View {
|
||||
GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
|
||||
|
||||
SliderSection(
|
||||
intervalMinutes: $intervalMinutes,
|
||||
countdownSeconds: $countdownSeconds,
|
||||
intervalRange: 5...90,
|
||||
countdownRange: 10...30,
|
||||
intervalSettings: $intervalSettings,
|
||||
countdownSettings: $countdownSettings,
|
||||
enabled: $enabled,
|
||||
type: "Look away",
|
||||
reminderText:
|
||||
"You will be reminded every \(intervalMinutes) minutes to look in the distance for \(countdownSeconds) seconds",
|
||||
previewFunc: showPreviewWindow
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
Spacer()
|
||||
@@ -98,7 +93,7 @@ struct LookAwaySetupView: View {
|
||||
window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]
|
||||
window.acceptsMouseMovedEvents = true
|
||||
|
||||
let contentView = LookAwayReminderView(countdownSeconds: countdownSeconds) {
|
||||
let contentView = LookAwayReminderView(countdownSeconds: countdownSettings.val ?? 20) {
|
||||
[weak window] in
|
||||
window?.close()
|
||||
}
|
||||
@@ -114,10 +109,11 @@ struct LookAwaySetupView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Look Away Setup View") {
|
||||
LookAwaySetupView(
|
||||
enabled: .constant(true),
|
||||
intervalMinutes: .constant(20),
|
||||
countdownSeconds: .constant(20)
|
||||
)
|
||||
}
|
||||
//TODO: add this back
|
||||
/*#Preview("Look Away Setup View") {*/
|
||||
/*LookAwaySetupView(*/
|
||||
/*enabled: .constant(true),*/
|
||||
/*intervalMinutes: .constant(20),*/
|
||||
/*countdownSeconds: .constant(20)*/
|
||||
/*)*/
|
||||
/*}*/
|
||||
|
||||
@@ -10,7 +10,7 @@ import SwiftUI
|
||||
|
||||
struct PostureSetupView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var intervalMinutes: Int
|
||||
@Binding var intervalSettings: RangeChoice
|
||||
var subtleReminderSize: ReminderSize = .medium
|
||||
@State private var previewWindowController: NSWindowController?
|
||||
|
||||
@@ -60,65 +60,11 @@ struct PostureSetupView: View {
|
||||
.glassEffectIfAvailable(
|
||||
GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
|
||||
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
Toggle("Enable Posture Reminders", isOn: $enabled)
|
||||
.font(.headline)
|
||||
|
||||
if enabled {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
Text("Remind me every:")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
HStack {
|
||||
Slider(
|
||||
value: Binding(
|
||||
get: { Double(intervalMinutes) },
|
||||
set: { intervalMinutes = Int($0) }
|
||||
), in: 15...90, step: 5)
|
||||
|
||||
Text("\(intervalMinutes) min")
|
||||
.frame(width: 60, alignment: .trailing)
|
||||
.monospacedDigit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
|
||||
|
||||
if enabled {
|
||||
Text(
|
||||
"You will be subtly reminded every \(intervalMinutes) minutes to check your posture"
|
||||
)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
} else {
|
||||
Text(
|
||||
"Posture reminders are currently disabled."
|
||||
)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
// Preview button
|
||||
Button(action: {
|
||||
showPreviewWindow()
|
||||
}) {
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: "eye")
|
||||
.foregroundColor(.white)
|
||||
Text("Preview Reminder")
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 10)
|
||||
.contentShape(RoundedRectangle(cornerRadius: 10))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffectIfAvailable(
|
||||
GlassStyle.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10)
|
||||
SliderSection(
|
||||
intervalSettings: $intervalSettings,
|
||||
enabled: $enabled,
|
||||
type: "Posture",
|
||||
previewFunc: showPreviewWindow
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user