Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "tipsy-ness" level selector on mobile #32

Merged
merged 2 commits into from
Mar 24, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions frontend/src/tipsyselector/circleselector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,13 @@ export function CircleSelector({
pressed.current.lastRegisteredInput = 0;
}

function onMove(event: React.MouseEvent<HTMLDivElement>) {
function onMove(this: HTMLDivElement, event: MouseEvent | TouchEvent) {
function isTouchEvent(event: Event): event is TouchEvent {
return (event as any).touches;
}

event.preventDefault();

/* Debounce and check for mouse press */
const currentTime = new Date().getTime();
// Mouse movement only, so the input must not change the value
Expand All @@ -116,10 +122,10 @@ export function CircleSelector({
}

// Rectangle containing all elements. Offsets are relative to the viewport.
const targetDimensionsInViewport: DOMRect = event.currentTarget.getBoundingClientRect();
const targetDimensionsInViewport: DOMRect = this.getBoundingClientRect();
const cursorPosition: Vector = new CartesianPoint(
event.clientX - targetDimensionsInViewport.left,
event.clientY - targetDimensionsInViewport.top
(isTouchEvent(event) ? event.touches[0].clientX : event.clientX) - targetDimensionsInViewport.left,
(isTouchEvent(event) ? event.touches[0].clientY : event.clientY) - targetDimensionsInViewport.top
);

const pointOnCircleCartesian = calculateClosestPointOnCircle(cursorPosition);
Expand Down Expand Up @@ -147,7 +153,26 @@ export function CircleSelector({
setValue(percentage);
}

return <div onMouseMove={onMove}
const containerRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const element = containerRef.current;
if (!element) {
return;
}

// Necessary as event listeners must not be passive (Event#preventDefault fails otherwise)
element.addEventListener("mousemove", onMove, { passive: false });
element.addEventListener("touchmove", onMove, { passive: false });

return () => {
element.removeEventListener("mousemove", onMove);
element.removeEventListener("touchmove", onMove);
}
// eslint demands 'onMove' to be in the dependencies array as well
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [containerRef]);

return <div ref={containerRef}
onTouchStart={onPress} onTouchEnd={onRelease} onMouseDown={onPress} onMouseUp={onRelease}>
<svg width={width} height={width}>
<OpenCircleSvg
Expand Down