mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 14:55:37 +00:00
harden explicit click zoom suggestions
This commit is contained in:
@@ -6,8 +6,13 @@ import {
|
||||
} from "./zoomSuggestionUtils";
|
||||
import type { CursorTelemetryPoint } from "../types";
|
||||
|
||||
function makeClick(timeMs: number, cx = 0.5, cy = 0.5): CursorTelemetryPoint {
|
||||
return { timeMs, cx, cy, interactionType: "click" };
|
||||
function makeClick(
|
||||
timeMs: number,
|
||||
cx = 0.5,
|
||||
cy = 0.5,
|
||||
interactionType: CursorTelemetryPoint["interactionType"] = "click",
|
||||
): CursorTelemetryPoint {
|
||||
return { timeMs, cx, cy, interactionType };
|
||||
}
|
||||
|
||||
function makeMove(timeMs: number, cx = 0.5, cy = 0.5): CursorTelemetryPoint {
|
||||
@@ -57,6 +62,24 @@ describe("buildInteractionZoomSuggestions (click-cluster logic)", () => {
|
||||
expect(result.suggestions).toHaveLength(1);
|
||||
});
|
||||
|
||||
it.each(["right-click", "middle-click"] as const)(
|
||||
"accepts %s telemetry like a standard click",
|
||||
(interactionType) => {
|
||||
const result = buildInteractionZoomSuggestions({
|
||||
cursorTelemetry: withMoves([makeClick(5_000, 0.5, 0.5, interactionType)], TOTAL_MS),
|
||||
totalMs: TOTAL_MS,
|
||||
defaultDurationMs: 3_000,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("ok");
|
||||
expect(result.suggestions).toHaveLength(1);
|
||||
|
||||
const [suggestion] = result.suggestions;
|
||||
expect(suggestion.start).toBe(5_000 - CLICK_CLUSTER_PAD_MS);
|
||||
expect(suggestion.end).toBe(5_000 + CLICK_CLUSTER_PAD_MS);
|
||||
},
|
||||
);
|
||||
|
||||
it("merges two clicks within 2500ms into one zoom track", () => {
|
||||
const telemetry = withMoves(
|
||||
[makeClick(4_000), makeClick(4_000 + CLICK_CLUSTER_MERGE_GAP_MS - 1)],
|
||||
|
||||
@@ -43,6 +43,18 @@ export interface InteractionZoomSuggestionResult {
|
||||
export const CLICK_CLUSTER_MERGE_GAP_MS = 2500;
|
||||
/** Padding added before the first click and after the last click in a cluster. */
|
||||
export const CLICK_CLUSTER_PAD_MS = 500;
|
||||
const EXPLICIT_CLICK_TYPES = new Set<NonNullable<CursorTelemetryPoint["interactionType"]>>([
|
||||
"click",
|
||||
"double-click",
|
||||
"right-click",
|
||||
"middle-click",
|
||||
]);
|
||||
|
||||
function isExplicitClickType(
|
||||
interactionType: CursorTelemetryPoint["interactionType"],
|
||||
): interactionType is NonNullable<CursorTelemetryPoint["interactionType"]> {
|
||||
return typeof interactionType === "string" && EXPLICIT_CLICK_TYPES.has(interactionType);
|
||||
}
|
||||
|
||||
function normalizeTelemetrySample(
|
||||
sample: CursorTelemetryPoint,
|
||||
@@ -188,9 +200,7 @@ export function detectInteractionCandidates(
|
||||
samples: CursorTelemetryPoint[],
|
||||
): CursorInteractionCandidate[] {
|
||||
// --- Phase 1: Explicit interaction events (from uiohook telemetry) ---
|
||||
const clickEvents = samples.filter(
|
||||
(s) => s.interactionType && s.interactionType !== "move" && s.interactionType !== "mouseup",
|
||||
);
|
||||
const clickEvents = samples.filter((sample) => isExplicitClickType(sample.interactionType));
|
||||
|
||||
const explicitInteractionCandidates: CursorInteractionCandidate[] = [];
|
||||
|
||||
@@ -354,10 +364,7 @@ export function buildInteractionZoomSuggestions(params: {
|
||||
|
||||
if (
|
||||
normalizedSamples.length === 1 &&
|
||||
normalizedSamples[0].interactionType !== "click" &&
|
||||
normalizedSamples[0].interactionType !== "double-click" &&
|
||||
normalizedSamples[0].interactionType !== "right-click" &&
|
||||
normalizedSamples[0].interactionType !== "middle-click"
|
||||
!isExplicitClickType(normalizedSamples[0].interactionType)
|
||||
) {
|
||||
return { status: "no-telemetry", suggestions: [] };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user