Skip to content

Commit

Permalink
Merge pull request #35 from fileverse/bugfix-heartbitui-onfill-call
Browse files Browse the repository at this point in the history
Bugfix heartbitui onfill call
  • Loading branch information
nadeem-fileverse committed Feb 21, 2024
2 parents 085f684 + 2a68394 commit 417d83f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/twelve-insects-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fileverse/heartbit-react": minor
---

Fixed bug where events where not called on fill complete
64 changes: 59 additions & 5 deletions packages/heartbit-react/src/components/HeartBitUI/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import type {
InternalHandlerRef,
TotalFillRange,
} from "./types";
import { HEART_CV_HEIGHT, HEART_CV_WIDTH, makeHeartCanvas } from "../../utils";
import {
HEART_CV_HEIGHT,
HEART_CV_WIDTH,
disableUpEvents,
makeHeartCanvas,
} from "../../utils";
import clx from "classnames";

const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
Expand All @@ -26,10 +31,15 @@ const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
isDisabled = false,
disableBeatingAnimation = false,
fillInterval = 750,
startFilling = false,
} = props;

const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

const autFillRef = useRef<ReturnType<typeof setInterval> | null>(null);

const canvasRef = useRef<HTMLCanvasElement | null>(null);

const [currentFillIdx, setCurrentFillIdx] = useState<TotalFillRange>(0);

useEffect(() => {
Expand All @@ -53,12 +63,53 @@ const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
fillPosition: startFillPos || defaultFillPos,
scale,
});

canvasRef.current = node;
setCanvasContext(context);
},
[defaultFillPos, scale, startFillPos]
);

const autoFillHeart = useCallback(() => {
if (!canvasContext || currentFillIdx >= 10 || !startFilling) return;

let idx = currentFillIdx;

autFillRef.current = setInterval(() => {
if (idx >= 10) {
if (onMouseUp && typeof onMouseUp === "function") {
if (canvasRef.current) disableUpEvents(canvasRef.current);
onMouseUp();
}
clearInterval(autFillRef.current as ReturnType<typeof setInterval>);
return;
}
canvasContext.reset();
makeHeartCanvas({
canvasContext,
fillPosition: idx + 1,
scale,
});
if (idx < 11) idx = idx + 1;

setCurrentFillIdx(idx);
}, fillInterval);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [canvasContext, fillInterval, scale, startFilling]);

useEffect(() => {
const cleanup = () => {
if (autFillRef.current)
clearInterval(autFillRef.current as ReturnType<typeof setInterval>);
};

if (startFilling) autoFillHeart();
else cleanup();

return () => {
cleanup();
};
}, [autoFillHeart, startFilling]);

const onMousedown = (
e:
| React.MouseEvent<HTMLCanvasElement>
Expand All @@ -71,6 +122,10 @@ const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
let idx = currentFillIdx;
intervalRef.current = setInterval(() => {
if (idx >= 10) {
if (onMouseUp && typeof onMouseUp === "function") {
if (canvasRef.current) disableUpEvents(canvasRef.current);
onMouseUp();
}
clearInterval(intervalRef.current as ReturnType<typeof setInterval>);
return;
}
Expand All @@ -81,7 +136,7 @@ const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
scale,
});

if (idx < 10) idx += 1;
if (idx < 11) idx += 1;

setCurrentFillIdx(idx);
}, fillInterval);
Expand All @@ -97,8 +152,6 @@ const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
scale,
});

setCanvasContext(canvasContext);

setCurrentFillIdx(startFillPos);
}, [canvasContext, defaultFillPos, scale, startFillPos]);

Expand Down Expand Up @@ -138,6 +191,7 @@ const HeartBitUI = forwardRef<InternalHandlerRef, HeartBitUIProps>(
onMouseUp={onMouseup}
onTouchStart={onMousedown}
onTouchEnd={onMouseup}
onContextMenu={(e) => e.preventDefault()}
className={clx(styles.heart, {
[styles.disabled]: isDisabled || disableBeatingAnimation,
})}
Expand Down
5 changes: 3 additions & 2 deletions packages/heartbit-react/src/components/HeartBitUI/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ export type TotalFillRange = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
type DefaultFillRange = 1 | 2 | 3 | 4 | 5;
export interface HeartBitUIProps {
onMouseUp?: (
event:
event?:
| React.MouseEvent<HTMLCanvasElement, MouseEvent>
| React.TouchEvent<HTMLCanvasElement>
) => void;
onMouseDown?: (
event:
event?:
| React.MouseEvent<HTMLCanvasElement, MouseEvent>
| React.TouchEvent<HTMLCanvasElement>
) => void;
Expand All @@ -17,6 +17,7 @@ export interface HeartBitUIProps {
isDisabled?: boolean;
disableBeatingAnimation?: boolean;
fillInterval?: number;
startFilling?: boolean;
}

export interface InternalHandlerRef {
Expand Down
23 changes: 23 additions & 0 deletions packages/heartbit-react/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,26 @@ export const getStartFillPosition = (totalMintsByUser: number) => {
if (totalMintsByUser < 60) return 0;
return 5;
};

export const addSelfDestructingEventListener = (
element: HTMLElement,
event: string,
callback: (event: Event) => void
) => {
const handler = (e: Event) => {
callback(e);
element.removeEventListener(event, handler, true);
};
element.addEventListener(event, handler, true);
};

export const disableUpEvents = (element: HTMLElement) => {
addSelfDestructingEventListener(element, "mouseup", (e) => {
e.stopImmediatePropagation();
e.stopPropagation();
});
addSelfDestructingEventListener(element, "touchend", (e) => {
e.stopImmediatePropagation();
e.stopPropagation();
});
};

0 comments on commit 417d83f

Please sign in to comment.