Skip to content

Commit f03130c

Browse files
jsonifyclaude
andauthored
feat: Convert Lite click interval to CPS with extended range (#19)
* feat: Convert Lite click interval to CPS with extended range - Replace fixed interval slider (0.1-10s) with logarithmic CPS slider - Support range from 100 CPS (0.01s) to 1 click per 5 minutes (300s) - Add dynamic formatting: shows CPS for fast speeds, descriptive text for slow - Include human-readable descriptions with emojis (⚡ Very Fast to 🦥 Ultra Slow) - Implement logarithmic scale for smooth control across wide range - Add validation clamping (0.01s min, 300s max) to prevent unsafe speeds - Update UI labels and help text to reflect new CPS-based interface Addresses user request for more precise control over click timing, especially for high-speed automation (up to 100 CPS). * refactor: Extract magic numbers and use switch statements Code quality improvements based on code review: - Add SpeedLimit enum with named constants for intervals and CPS limits - minInterval (0.01s = 100 CPS) - maxInterval (300s = 1 click per 5 min) - safeGuardInterval (0.001s to prevent division by zero) - Add SpeedThreshold enum with named constants for speed tiers - CPS thresholds for formatting (high/medium/low) - CPS thresholds for descriptions (veryFast/fast/normal) - Interval thresholds for slow speeds (slow/verySlow) - Refactor formatClickSpeed() to use switch statement - Replace if/else chain with pattern matching - More idiomatic Swift code - Refactor describeClickSpeed() to use nested switch statements - Primary switch on CPS for fast speeds - Secondary switch on interval for slow speeds - Eliminates all magic numbers Benefits: - Self-documenting code with clear intent - Easier to maintain and adjust thresholds - More idiomatic Swift patterns - Better readability --------- Co-authored-by: Claude <[email protected]>
1 parent fe58959 commit f03130c

File tree

1 file changed

+110
-6
lines changed

1 file changed

+110
-6
lines changed

Sources/ClickIt/Lite/SimplifiedMainView.swift

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@ import SwiftUI
99

1010
struct SimplifiedMainView: View {
1111

12+
// MARK: - Speed Configuration
13+
14+
/// Speed limits for click intervals
15+
private enum SpeedLimit {
16+
static let minInterval: Double = 0.01 // 100 CPS
17+
static let maxInterval: Double = 300.0 // 1 click per 5 min
18+
static var minCPS: Double { 1.0 / maxInterval }
19+
static var maxCPS: Double { 1.0 / minInterval }
20+
static let safeGuardInterval: Double = 0.001 // Prevents division by zero
21+
}
22+
23+
/// Thresholds for speed descriptions and formatting
24+
private enum SpeedThreshold {
25+
// CPS thresholds for formatting
26+
static let highCPS: Double = 10.0
27+
static let mediumCPS: Double = 1.0
28+
static let lowCPS: Double = 0.1
29+
30+
// CPS thresholds for descriptions
31+
static let veryFastCPS: Double = 50.0
32+
static let fastCPS: Double = 10.0
33+
static let normalCPS: Double = 1.0
34+
35+
// Interval thresholds for descriptions (seconds)
36+
static let slowInterval: Double = 60.0
37+
static let verySlowInterval: Double = 120.0
38+
}
39+
1240
// MARK: - Properties
1341

1442
@StateObject private var viewModel = SimpleViewModel()
@@ -164,26 +192,102 @@ struct SimplifiedMainView: View {
164192
private var clickIntervalSection: some View {
165193
VStack(alignment: .leading, spacing: 8) {
166194
HStack {
167-
Text("Click Interval")
195+
Text("Click Speed")
168196
.font(.headline)
169197
Spacer()
170-
Text("\(String(format: "%.1f", viewModel.clickInterval))s")
198+
Text(formatClickSpeed(interval: viewModel.clickInterval))
171199
.font(.system(.body, design: .monospaced))
172200
.foregroundColor(.blue)
173201
}
174202

175-
Slider(value: $viewModel.clickInterval, in: 0.1...10.0, step: 0.1)
176-
.disabled(viewModel.isRunning)
203+
// Logarithmic slider for CPS
204+
// Maps log scale to linear slider for better UX across wide range
205+
Slider(
206+
value: Binding(
207+
get: {
208+
// Convert interval to log(CPS)
209+
let cps = 1.0 / max(viewModel.clickInterval, SpeedLimit.safeGuardInterval)
210+
return log10(cps)
211+
},
212+
set: { logCPS in
213+
// Convert log(CPS) back to interval
214+
let cps = pow(10.0, logCPS)
215+
let interval = 1.0 / cps
216+
// Clamp to valid range
217+
viewModel.clickInterval = min(max(interval, SpeedLimit.minInterval), SpeedLimit.maxInterval)
218+
}
219+
),
220+
in: log10(SpeedLimit.minCPS)...log10(SpeedLimit.maxCPS)
221+
)
222+
.disabled(viewModel.isRunning)
177223

178224
HStack {
179-
Text("0.1s")
225+
Text("1 / 5 min")
180226
.font(.caption)
181227
.foregroundColor(.secondary)
182228
Spacer()
183-
Text("10s")
229+
Text("100 CPS")
184230
.font(.caption)
185231
.foregroundColor(.secondary)
186232
}
233+
234+
// Human-readable description
235+
Text(describeClickSpeed(interval: viewModel.clickInterval))
236+
.font(.caption)
237+
.foregroundColor(.secondary)
238+
.multilineTextAlignment(.center)
239+
.frame(maxWidth: .infinity)
240+
}
241+
}
242+
243+
// MARK: - Helper Methods
244+
245+
/// Format click speed for display
246+
private func formatClickSpeed(interval: Double) -> String {
247+
let cps = 1.0 / interval
248+
let format: String
249+
250+
switch cps {
251+
case SpeedThreshold.highCPS...:
252+
format = "%.0f CPS"
253+
case SpeedThreshold.mediumCPS..<SpeedThreshold.highCPS:
254+
format = "%.1f CPS"
255+
case SpeedThreshold.lowCPS..<SpeedThreshold.mediumCPS:
256+
format = "%.2f CPS"
257+
default:
258+
format = "%.3f CPS"
259+
}
260+
261+
return String(format: format, cps)
262+
}
263+
264+
/// Describe click speed in human-readable terms
265+
private func describeClickSpeed(interval: Double) -> String {
266+
let cps = 1.0 / interval
267+
268+
switch cps {
269+
case SpeedThreshold.veryFastCPS...:
270+
return "⚡ Very Fast - \(String(format: "%.1f", interval * 1000))ms per click"
271+
272+
case SpeedThreshold.fastCPS..<SpeedThreshold.veryFastCPS:
273+
return "🚀 Fast - \(String(format: "%.2f", interval))s per click"
274+
275+
case SpeedThreshold.normalCPS..<SpeedThreshold.fastCPS:
276+
return "⏱️ Normal - 1 click every \(String(format: "%.1f", interval))s"
277+
278+
default:
279+
// For CPS < 1.0, describe by interval instead
280+
switch interval {
281+
case ..<SpeedThreshold.slowInterval:
282+
return "🐌 Slow - 1 click every \(String(format: "%.1f", interval))s"
283+
284+
case SpeedThreshold.slowInterval..<SpeedThreshold.verySlowInterval:
285+
return "🐢 Very Slow - 1 click every \(Int(interval))s (~\(Int(interval/60)) min)"
286+
287+
default:
288+
let minutes = Int(interval / 60)
289+
return "🦥 Ultra Slow - 1 click every \(minutes) minutes"
290+
}
187291
}
188292
}
189293

0 commit comments

Comments
 (0)