From c487d075be0c741d936536e8b3eee41091918b96 Mon Sep 17 00:00:00 2001 From: David Campos Date: Fri, 24 Apr 2026 23:54:03 +0400 Subject: [PATCH] fix: move cadence summary to rate input --- src-tauri/src/engine/worker.rs | 3 ++- src/cadence.ts | 26 +++++++++++++++++++ src/components/CadenceInput.tsx | 14 +++++++++- .../panels/advanced/AdvancedPanel.css | 17 ++++++++++++ .../panels/advanced/LimitsSection.tsx | 13 ++++++++-- src/components/panels/advanced/shared.tsx | 3 +-- 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src-tauri/src/engine/worker.rs b/src-tauri/src/engine/worker.rs index a815845..f7c6f6a 100644 --- a/src-tauri/src/engine/worker.rs +++ b/src-tauri/src/engine/worker.rs @@ -414,7 +414,8 @@ pub fn start_clicker(config: ClickerConfig, control: RunControl) -> RunOutcome { } } - let per_tick_clicks = batch_size.saturating_mul(if config.double_click_enabled { 2 } else { 1 }); + let per_tick_clicks = + batch_size.saturating_mul(if config.double_click_enabled { 2 } else { 1 }); let requested_clicks = if config.sequence_enabled && !config.sequence_points.is_empty() { sequence_clicks_remaining.min(per_tick_clicks) } else { diff --git a/src/cadence.ts b/src/cadence.ts index 1ef3462..70468d6 100644 --- a/src/cadence.ts +++ b/src/cadence.ts @@ -56,6 +56,32 @@ export function getMaxDoubleClickDelayMs(settings: CadenceSettings): number { return cps > 0 ? Math.max(20, Math.floor(1000 / cps) - 2) : 9999; } +export function formatMillisecondsSummary(totalMs: number): string { + const roundedMs = Math.max(1, Math.round(totalMs)); + const hours = Math.floor(roundedMs / 3_600_000); + const remainderAfterHours = roundedMs % 3_600_000; + const minutes = Math.floor(remainderAfterHours / 60_000); + const remainderAfterMinutes = remainderAfterHours % 60_000; + const seconds = Math.floor(remainderAfterMinutes / 1_000); + const milliseconds = remainderAfterMinutes % 1_000; + const parts: string[] = []; + + if (hours > 0) { + parts.push(`${hours}h`); + } + if (minutes > 0) { + parts.push(`${minutes}m`); + } + if (seconds > 0) { + parts.push(`${seconds}s`); + } + if (milliseconds > 0 || parts.length === 0) { + parts.push(`${milliseconds}ms`); + } + + return parts.join(" "); +} + export function formatDurationSummary(settings: CadenceSettings): string { const parts: string[] = []; diff --git a/src/components/CadenceInput.tsx b/src/components/CadenceInput.tsx index e1e8bf4..719af9b 100644 --- a/src/components/CadenceInput.tsx +++ b/src/components/CadenceInput.tsx @@ -1,6 +1,10 @@ import type { ChangeEvent, CSSProperties, FocusEvent, WheelEvent } from "react"; import "./panels/advanced/AdvancedPanel.css"; -import { RATE_INPUT_MODE_OPTIONS } from "../cadence"; +import { + formatMillisecondsSummary, + getEffectiveIntervalMs, + RATE_INPUT_MODE_OPTIONS, +} from "../cadence"; import { normalizeIntegerRaw } from "../numberInput"; import type { RateInputMode, Settings } from "../store"; import { useTranslation } from "../i18n"; @@ -352,6 +356,9 @@ export default function CadenceInput({ settings, update, variant }: Props) { ))} ); + const rateCadenceDisplay = `${formatMillisecondsSummary( + getEffectiveIntervalMs(settings), + )} ${t("advanced.delay")}`; return (
@@ -531,6 +538,11 @@ export default function CadenceInput({ settings, update, variant }: Props) {
{modeToggle} + {settings.rateInputMode === "rate" ? ( +
+ {rateCadenceDisplay} +
+ ) : null} ); } diff --git a/src/components/panels/advanced/AdvancedPanel.css b/src/components/panels/advanced/AdvancedPanel.css index 9ecfdad..c6775a7 100644 --- a/src/components/panels/advanced/AdvancedPanel.css +++ b/src/components/panels/advanced/AdvancedPanel.css @@ -152,6 +152,19 @@ input[type="number"]::-webkit-outer-spin-button { flex-wrap: wrap; } +.adv-cadence-summary-row { + display: flex; + align-items: center; + min-height: 1rem; +} + +.adv-cadence-summary { + color: var(--text-dim); + font-family: 'DMSans', sans-serif; + font-size: 0.75rem; + font-weight: var(--font-weight-md); +} + .adv-axis-label { margin-left: 0; margin-right: 0.25rem; @@ -214,6 +227,10 @@ input[type="number"]::-webkit-outer-spin-button { font-size: 0.875rem; font-weight: var(--font-weight-hv); color: var(--text-primary); + background: transparent; + border: none; + outline: none; + padding: 0; } .adv-unit { diff --git a/src/components/panels/advanced/LimitsSection.tsx b/src/components/panels/advanced/LimitsSection.tsx index bd3826f..365fbda 100644 --- a/src/components/panels/advanced/LimitsSection.tsx +++ b/src/components/panels/advanced/LimitsSection.tsx @@ -22,19 +22,28 @@ export default function LimitsSection({ settings, update, showInfo }: Props) { ); useEffect(() => { + let nextMode: "clicks" | "time" | null = null; + if ( settings.timeLimitEnabled && !settings.clickLimitEnabled && mode !== "time" ) { - setMode("time"); + nextMode = "time"; } else if ( settings.clickLimitEnabled && !settings.timeLimitEnabled && mode !== "clicks" ) { - setMode("clicks"); + nextMode = "clicks"; + } + + if (nextMode === null) { + return; } + + const id = window.requestAnimationFrame(() => setMode(nextMode)); + return () => window.cancelAnimationFrame(id); }, [settings.clickLimitEnabled, settings.timeLimitEnabled, mode]); useEffect(() => { diff --git a/src/components/panels/advanced/shared.tsx b/src/components/panels/advanced/shared.tsx index 07cb9f7..05fc097 100644 --- a/src/components/panels/advanced/shared.tsx +++ b/src/components/panels/advanced/shared.tsx @@ -224,7 +224,6 @@ export function InfoIcon({ text }: { text: string }) { return; } - updateTooltipPosition(); const id = window.requestAnimationFrame(updateTooltipPosition); const handleReposition = () => { @@ -387,4 +386,4 @@ export function AdvDropdown({ )} ); -} \ No newline at end of file +}