@cuemath/leap 3.3.8 → 3.3.9-as2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/features/class-timer/animate.js +102 -0
- package/dist/features/class-timer/animate.js.map +1 -0
- package/dist/features/class-timer/animations/open-close.js +94 -0
- package/dist/features/class-timer/animations/open-close.js.map +1 -0
- package/dist/features/class-timer/animations/ripple.js +44 -0
- package/dist/features/class-timer/animations/ripple.js.map +1 -0
- package/dist/features/class-timer/class-timer.js +140 -0
- package/dist/features/class-timer/class-timer.js.map +1 -0
- package/dist/features/class-timer/clock.js +26 -0
- package/dist/features/class-timer/clock.js.map +1 -0
- package/dist/features/class-timer/constants.js +27 -0
- package/dist/features/class-timer/constants.js.map +1 -0
- package/dist/features/class-timer/timer.js +65 -0
- package/dist/features/class-timer/timer.js.map +1 -0
- package/dist/features/hooks/use-visibility-change.js +12 -0
- package/dist/features/hooks/use-visibility-change.js.map +1 -0
- package/dist/features/ui/constants/z-index.js +4 -1
- package/dist/features/ui/constants/z-index.js.map +1 -1
- package/dist/features/utils/utils.js +18 -18
- package/dist/features/utils/utils.js.map +1 -1
- package/dist/features/worksheet/worksheet/constants.js +18 -12
- package/dist/features/worksheet/worksheet/constants.js.map +1 -1
- package/dist/index.d.ts +72 -0
- package/dist/index.js +524 -514
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsxs as f, Fragment as g, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { memo as N, useState as k, useRef as w, useEffect as u, useCallback as c } from "react";
|
|
3
|
+
import i from "styled-components";
|
|
4
|
+
import O from "../../assets/line-icons/icons/plus.js";
|
|
5
|
+
import D from "../hooks/use-audio-player.js";
|
|
6
|
+
import R from "../hooks/use-previous.js";
|
|
7
|
+
import X from "../ui/buttons/clickable/clickable.js";
|
|
8
|
+
import a from "../ui/layout/flex-view.js";
|
|
9
|
+
import m from "../ui/text/text.js";
|
|
10
|
+
import { ALERT_AUDIO_LIST as F } from "../worksheet/worksheet/constants.js";
|
|
11
|
+
import I from "./animations/open-close.js";
|
|
12
|
+
import { ANIMATION_TIME as r, TIME_LEFT_IDLE as M, LAST_FIVE as y, START_TIMER as z, EXTEND_IDLE as V } from "./constants.js";
|
|
13
|
+
const W = i(a)`
|
|
14
|
+
position: absolute;
|
|
15
|
+
top: -8px;
|
|
16
|
+
right: 8px;
|
|
17
|
+
z-index: ${({ theme: o }) => o.zIndex.EXTEND_CLASS_ANIMATION_3};
|
|
18
|
+
`, v = i(m)`
|
|
19
|
+
padding-left: 4px;
|
|
20
|
+
padding-right: 8px;
|
|
21
|
+
`, j = i(a)`
|
|
22
|
+
flex-flow: nowrap;
|
|
23
|
+
z-index: ${({ theme: o }) => o.zIndex.EXTEND_CLASS_ANIMATION_2};
|
|
24
|
+
`, P = i(a)`
|
|
25
|
+
position: fixed;
|
|
26
|
+
top: 0;
|
|
27
|
+
bottom: 0;
|
|
28
|
+
left: 0;
|
|
29
|
+
right: 0;
|
|
30
|
+
background: rgba(0, 0, 0, 0.4);
|
|
31
|
+
z-index: ${({ theme: o }) => o.zIndex.EXTEND_CLASS_ANIMATION_1};
|
|
32
|
+
`, B = (o) => {
|
|
33
|
+
const {
|
|
34
|
+
animateClock: t,
|
|
35
|
+
classStartedTime: E,
|
|
36
|
+
duration: x,
|
|
37
|
+
onExtendClass: _ = () => {
|
|
38
|
+
},
|
|
39
|
+
setAnimateClock: d,
|
|
40
|
+
setStartTimer: p,
|
|
41
|
+
showExtendIcon: C = !1
|
|
42
|
+
} = o, [$, l] = k(!1), n = Math.floor(x - (+/* @__PURE__ */ new Date() - E) / 1e3), h = C && n <= r.LAST_FIVE, A = R(t), s = w(null);
|
|
43
|
+
u(() => {
|
|
44
|
+
t && !A && (s.current = setTimeout(() => {
|
|
45
|
+
l(!0);
|
|
46
|
+
}, 1e3));
|
|
47
|
+
}, [t, A]), u(() => () => {
|
|
48
|
+
s.current && clearTimeout(s.current);
|
|
49
|
+
}, []);
|
|
50
|
+
const L = c(() => {
|
|
51
|
+
d(!1);
|
|
52
|
+
}, [d]), T = D(F), b = c(() => {
|
|
53
|
+
p(!0), T("ALERT");
|
|
54
|
+
}, [T, p]), S = c(() => {
|
|
55
|
+
l(!1);
|
|
56
|
+
}, [l]);
|
|
57
|
+
return /* @__PURE__ */ f(g, { children: [
|
|
58
|
+
n <= r.LAST_FIVE && t && /* @__PURE__ */ e(P, {}),
|
|
59
|
+
/* @__PURE__ */ e(
|
|
60
|
+
I,
|
|
61
|
+
{
|
|
62
|
+
background: n <= r.LAST_FIVE ? "ORANGE_4" : "YELLOW_3",
|
|
63
|
+
onAnimationComplete: L,
|
|
64
|
+
onOpenAnimationComplete: b,
|
|
65
|
+
visible: t,
|
|
66
|
+
idleTime: M,
|
|
67
|
+
children: /* @__PURE__ */ f(
|
|
68
|
+
j,
|
|
69
|
+
{
|
|
70
|
+
$flexDirection: "row",
|
|
71
|
+
$alignItems: "center",
|
|
72
|
+
$width: "100%",
|
|
73
|
+
$justifyContent: "space-around",
|
|
74
|
+
$borderRadiusX: 1.25,
|
|
75
|
+
$gutterX: 0.35,
|
|
76
|
+
$gapX: 0.35,
|
|
77
|
+
$flexGapX: 0.25,
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ e(m, { $renderAs: "ac3-black", children: n <= r.LAST_FIVE ? `0${y / 60}:00` : `${z / 60}:00` }),
|
|
80
|
+
/* @__PURE__ */ e(m, { $renderAs: "ac3-black", children: "Left" })
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
h && /* @__PURE__ */ e(W, { children: /* @__PURE__ */ e(
|
|
87
|
+
I,
|
|
88
|
+
{
|
|
89
|
+
onAnimationComplete: S,
|
|
90
|
+
background: "BLACK",
|
|
91
|
+
Icon: /* @__PURE__ */ e(X, { label: "Extend Class", onClick: _, children: /* @__PURE__ */ e(a, { $background: "WHITE", $borderRadiusX: 1.25, $borderColor: "BLACK_3", children: /* @__PURE__ */ e(O, { width: 16, height: 16 }) }) }),
|
|
92
|
+
visible: $,
|
|
93
|
+
idleTime: V,
|
|
94
|
+
children: /* @__PURE__ */ e(v, { $color: "WHITE", $renderAs: "body3", children: "Extend Class" })
|
|
95
|
+
}
|
|
96
|
+
) })
|
|
97
|
+
] });
|
|
98
|
+
}, ne = N(B);
|
|
99
|
+
export {
|
|
100
|
+
ne as default
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=animate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animate.js","sources":["../../../src/features/class-timer/animate.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, memo } from 'react';\nimport styled from 'styled-components';\n\nimport PlusIcon from '../../assets/line-icons/icons/plus';\nimport useAudioPlayer from '../hooks/use-audio-player';\nimport usePrevious from '../hooks/use-previous';\nimport Clickable from '../ui/buttons/clickable/clickable';\nimport FlexView from '../ui/layout/flex-view';\nimport Text from '../ui/text/text';\nimport { ALERT_AUDIO_LIST } from '../worksheet/worksheet/constants';\nimport OpenCloseAnimation from './animations/open-close';\nimport { ANIMATION_TIME, EXTEND_IDLE, LAST_FIVE, START_TIMER, TIME_LEFT_IDLE } from './constants';\n\nconst IconWrapper = styled(FlexView)`\n position: absolute;\n top: -8px;\n right: 8px;\n z-index: ${({ theme }) => theme.zIndex.EXTEND_CLASS_ANIMATION_3};\n`;\n\nconst StyledText = styled(Text)`\n padding-left: 4px;\n padding-right: 8px;\n`;\n\nconst NoWrapRow = styled(FlexView)`\n flex-flow: nowrap;\n z-index: ${({ theme }) => theme.zIndex.EXTEND_CLASS_ANIMATION_2};\n`;\n\nconst OpacityWrapper = styled(FlexView)`\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: ${({ theme }) => theme.zIndex.EXTEND_CLASS_ANIMATION_1};\n`;\n\ninterface AnimateProps {\n animateClock: boolean;\n classStartedTime: number;\n duration: number;\n onExtendClass?: () => void;\n setAnimateClock: (value: boolean) => void;\n setStartTimer: (value: boolean) => void;\n showExtendIcon?: boolean;\n}\n\nconst Animate = (props: AnimateProps) => {\n const {\n animateClock,\n classStartedTime,\n duration,\n onExtendClass = () => {},\n setAnimateClock,\n setStartTimer,\n showExtendIcon = false,\n } = props;\n const [animateTip, setAnimateTip] = useState(false);\n const remainingTime = Math.floor(duration - (+new Date() - classStartedTime) / 1000); // in seconds\n const showIcon = showExtendIcon && remainingTime <= ANIMATION_TIME.LAST_FIVE;\n const previousAnimateClock = usePrevious(animateClock);\n const timer = useRef<NodeJS.Timeout | null>(null);\n\n useEffect(() => {\n if (animateClock && !previousAnimateClock) {\n timer.current = setTimeout(() => {\n setAnimateTip(true);\n }, 1000);\n }\n }, [animateClock, previousAnimateClock]);\n\n useEffect(() => {\n return () => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n };\n }, []);\n\n const onClockAnimationComplete = useCallback(() => {\n setAnimateClock(false);\n }, [setAnimateClock]);\n const playNotifSound = useAudioPlayer(ALERT_AUDIO_LIST);\n\n const onOpenAnimationComplete = useCallback(() => {\n setStartTimer(true);\n playNotifSound('ALERT');\n }, [playNotifSound, setStartTimer]);\n\n const onAnimateComplete = useCallback(() => {\n setAnimateTip(false);\n }, [setAnimateTip]);\n\n return (\n <>\n {remainingTime <= ANIMATION_TIME.LAST_FIVE && animateClock && <OpacityWrapper />}\n <OpenCloseAnimation\n background={remainingTime <= ANIMATION_TIME.LAST_FIVE ? 'ORANGE_4' : 'YELLOW_3'}\n onAnimationComplete={onClockAnimationComplete}\n onOpenAnimationComplete={onOpenAnimationComplete}\n visible={animateClock}\n idleTime={TIME_LEFT_IDLE}\n >\n <NoWrapRow\n $flexDirection=\"row\"\n $alignItems=\"center\"\n $width=\"100%\"\n $justifyContent=\"space-around\"\n $borderRadiusX={1.25}\n $gutterX={0.35}\n $gapX={0.35}\n $flexGapX={0.25}\n >\n <Text $renderAs=\"ac3-black\">\n {remainingTime <= ANIMATION_TIME.LAST_FIVE\n ? `0${LAST_FIVE / 60}:00`\n : `${START_TIMER / 60}:00`}\n </Text>\n <Text $renderAs=\"ac3-black\">Left</Text>\n </NoWrapRow>\n </OpenCloseAnimation>\n {showIcon && (\n <IconWrapper>\n <OpenCloseAnimation\n onAnimationComplete={onAnimateComplete}\n background=\"BLACK\"\n Icon={\n <Clickable label=\"Extend Class\" onClick={onExtendClass}>\n <FlexView $background=\"WHITE\" $borderRadiusX={1.25} $borderColor=\"BLACK_3\">\n <PlusIcon width={16} height={16} />\n </FlexView>\n </Clickable>\n }\n visible={animateTip}\n idleTime={EXTEND_IDLE}\n >\n <StyledText $color=\"WHITE\" $renderAs=\"body3\">\n Extend Class\n </StyledText>\n </OpenCloseAnimation>\n </IconWrapper>\n )}\n </>\n );\n};\n\nexport default memo(Animate);\n"],"names":["IconWrapper","styled","FlexView","theme","StyledText","Text","NoWrapRow","OpacityWrapper","Animate","props","animateClock","classStartedTime","duration","onExtendClass","setAnimateClock","setStartTimer","showExtendIcon","animateTip","setAnimateTip","useState","remainingTime","showIcon","ANIMATION_TIME","previousAnimateClock","usePrevious","timer","useRef","useEffect","onClockAnimationComplete","useCallback","playNotifSound","useAudioPlayer","ALERT_AUDIO_LIST","onOpenAnimationComplete","onAnimateComplete","jsxs","Fragment","jsx","OpenCloseAnimation","TIME_LEFT_IDLE","LAST_FIVE","START_TIMER","Clickable","PlusIcon","EXTEND_IDLE","Animate$1","memo"],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsxs as I, jsx as $ } from "react/jsx-runtime";
|
|
2
|
+
import { memo as g, useState as p, useRef as y, useEffect as f } from "react";
|
|
3
|
+
import u, { keyframes as w, css as h } from "styled-components";
|
|
4
|
+
import x from "../../ui/layout/flex-view.js";
|
|
5
|
+
const E = w`
|
|
6
|
+
0% {
|
|
7
|
+
transform: translateX(-100%);
|
|
8
|
+
}
|
|
9
|
+
100% {
|
|
10
|
+
transform: translateX(0%);
|
|
11
|
+
}
|
|
12
|
+
`, R = w`
|
|
13
|
+
0% {
|
|
14
|
+
transform: translateX(0%);
|
|
15
|
+
}
|
|
16
|
+
100% {
|
|
17
|
+
transform: translateX(-100%);
|
|
18
|
+
}
|
|
19
|
+
`, d = 1 * 1e3, X = 1.5 * 1e3, z = u(x)`
|
|
20
|
+
position: absolute;
|
|
21
|
+
z-index: 10;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
`, M = u.div`
|
|
24
|
+
position: absolute;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
z-index: 1;
|
|
27
|
+
`, b = u(x)`
|
|
28
|
+
animation-name: ${({ $animate: t }) => t ? E : R};
|
|
29
|
+
max-width: fit-content;
|
|
30
|
+
animation-duration: ${d / 1e3}s;
|
|
31
|
+
animation-timing-function: ease-in-out;
|
|
32
|
+
animation-fill-mode: forwards;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
height: 100%;
|
|
36
|
+
${({ $isIcon: t, $size: i }) => t && h`
|
|
37
|
+
padding-left: ${i}px;
|
|
38
|
+
`};
|
|
39
|
+
${({ $isVisible: t }) => !t && h`
|
|
40
|
+
visibility: hidden;
|
|
41
|
+
`};
|
|
42
|
+
`, j = ({
|
|
43
|
+
background: t,
|
|
44
|
+
children: i,
|
|
45
|
+
Icon: n = null,
|
|
46
|
+
onAnimationComplete: s,
|
|
47
|
+
onOpenAnimationComplete: a,
|
|
48
|
+
size: T = null,
|
|
49
|
+
visible: r,
|
|
50
|
+
idleTime: l = X
|
|
51
|
+
}) => {
|
|
52
|
+
const [e, m] = p(!1), o = y(!1);
|
|
53
|
+
return f(() => {
|
|
54
|
+
r && (o.current = !1, m(!0));
|
|
55
|
+
}, [r]), f(() => {
|
|
56
|
+
if (e) {
|
|
57
|
+
const c = setTimeout(() => {
|
|
58
|
+
o.current = !0, m(!1), a == null || a();
|
|
59
|
+
}, d + l);
|
|
60
|
+
return () => {
|
|
61
|
+
clearTimeout(c);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}, [e, a, l]), f(() => {
|
|
65
|
+
if (r && !e && o.current) {
|
|
66
|
+
const c = setTimeout(() => {
|
|
67
|
+
s == null || s();
|
|
68
|
+
}, d);
|
|
69
|
+
return () => {
|
|
70
|
+
clearTimeout(c);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}, [r, e, s]), /* @__PURE__ */ I(z, { $flexDirection: "row", $alignItems: "center", $borderRadius: 16, children: [
|
|
74
|
+
n && /* @__PURE__ */ $(M, { children: n }),
|
|
75
|
+
/* @__PURE__ */ $(
|
|
76
|
+
b,
|
|
77
|
+
{
|
|
78
|
+
$alignItems: "center",
|
|
79
|
+
$animate: e,
|
|
80
|
+
$background: t,
|
|
81
|
+
$borderRadius: 16,
|
|
82
|
+
$isIcon: !!n,
|
|
83
|
+
$isVisible: r,
|
|
84
|
+
$size: T,
|
|
85
|
+
$hidden: !r,
|
|
86
|
+
children: i
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
] });
|
|
90
|
+
}, S = g(j);
|
|
91
|
+
export {
|
|
92
|
+
S as default
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=open-close.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-close.js","sources":["../../../../src/features/class-timer/animations/open-close.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, memo } from 'react';\nimport styled, { css, keyframes } from 'styled-components';\n\nimport FlexView from '../../ui/layout/flex-view';\n\nconst FillAnimation = keyframes`\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(0%);\n }\n`;\n\nconst EmptyAnimation = keyframes`\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(-100%);\n }\n`;\n\nconst ANIMATION_TIME = 1 * 1000; // 1 seconds\nconst IDLE_TIME = 1.5 * 1000;\n\nconst StyledRow = styled(FlexView)`\n position: absolute;\n z-index: 10;\n overflow: hidden;\n`;\n\nconst IconWrapper = styled.div`\n position: absolute;\n cursor: pointer;\n z-index: 1;\n`;\n\nconst Wrapper = styled(FlexView)<{\n $animate: boolean;\n $isIcon: boolean;\n $isVisible: boolean;\n $size: number | null;\n}>`\n animation-name: ${({ $animate }) => ($animate ? FillAnimation : EmptyAnimation)};\n max-width: fit-content;\n animation-duration: ${ANIMATION_TIME / 1000}s;\n animation-timing-function: ease-in-out;\n animation-fill-mode: forwards;\n overflow: hidden;\n white-space: nowrap;\n height: 100%;\n ${({ $isIcon, $size }) =>\n $isIcon &&\n css`\n padding-left: ${$size}px;\n `};\n ${({ $isVisible }) =>\n !$isVisible &&\n css`\n visibility: hidden;\n `};\n`;\n\ninterface OpenCloseAnimationProps {\n background: 'ORANGE_4' | 'YELLOW_3' | 'BLACK';\n children: React.ReactNode;\n idleTime?: number;\n Icon?: React.ReactNode;\n onAnimationComplete?: () => void;\n onOpenAnimationComplete?: () => void;\n size?: number | null;\n visible: boolean;\n}\n\nconst OpenCloseAnimation: React.FC<OpenCloseAnimationProps> = ({\n background,\n children,\n Icon = null,\n onAnimationComplete,\n onOpenAnimationComplete,\n size = null,\n visible,\n idleTime = IDLE_TIME,\n}) => {\n const [animate, setAnimate] = useState(false);\n const prevAnimate = useRef(false);\n\n useEffect(() => {\n if (visible) {\n prevAnimate.current = false;\n setAnimate(true);\n }\n }, [visible]);\n\n useEffect(() => {\n if (animate) {\n const animateTimer = setTimeout(() => {\n prevAnimate.current = true;\n setAnimate(false);\n onOpenAnimationComplete?.();\n }, ANIMATION_TIME + idleTime);\n\n return () => {\n clearTimeout(animateTimer);\n };\n }\n }, [animate, onOpenAnimationComplete, idleTime]);\n\n useEffect(() => {\n if (visible && !animate && prevAnimate.current) {\n const hideTimer = setTimeout(() => {\n onAnimationComplete?.();\n }, ANIMATION_TIME);\n\n return () => {\n clearTimeout(hideTimer);\n };\n }\n }, [visible, animate, onAnimationComplete]);\n\n return (\n <StyledRow $flexDirection=\"row\" $alignItems=\"center\" $borderRadius={16}>\n {Icon && <IconWrapper>{Icon}</IconWrapper>}\n <Wrapper\n $alignItems=\"center\"\n $animate={animate}\n $background={background}\n $borderRadius={16}\n $isIcon={!!Icon}\n $isVisible={visible}\n $size={size}\n $hidden={!visible}\n >\n {children}\n </Wrapper>\n </StyledRow>\n );\n};\n\nexport default memo(OpenCloseAnimation);\n"],"names":["FillAnimation","keyframes","EmptyAnimation","ANIMATION_TIME","IDLE_TIME","StyledRow","styled","FlexView","IconWrapper","Wrapper","$animate","$isIcon","$size","css","$isVisible","OpenCloseAnimation","background","children","Icon","onAnimationComplete","onOpenAnimationComplete","size","visible","idleTime","animate","setAnimate","useState","prevAnimate","useRef","useEffect","animateTimer","hideTimer","jsx","OpenCloseAnimation$1","memo"],"mappings":";;;;AAKA,MAAMA,IAAgBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAShBC,IAAiBD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASjBE,IAAiB,IAAI,KACrBC,IAAY,MAAM,KAElBC,IAAYC,EAAOC,CAAQ;AAAA;AAAA;AAAA;AAAA,GAM3BC,IAAcF,EAAO;AAAA;AAAA;AAAA;AAAA,GAMrBG,IAAUH,EAAOC,CAAQ;AAAA,oBAMX,CAAC,EAAE,UAAAG,EAAA,MAAgBA,IAAWV,IAAgBE,CAAe;AAAA;AAAA,wBAEzDC,IAAiB,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMzC,CAAC,EAAE,SAAAQ,GAAS,OAAAC,EAAA,MACZD,KACAE;AAAA,sBACkBD,CAAK;AAAA,KACtB;AAAA,IACD,CAAC,EAAE,YAAAE,EAAW,MACd,CAACA,KACDD;AAAA;AAAA,KAEC;AAAA,GAcCE,IAAwD,CAAC;AAAA,EAC7D,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,qBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,SAAAC;AAAA,EACA,UAAAC,IAAWnB;AACb,MAAM;AACJ,QAAM,CAACoB,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtCC,IAAcC,EAAO,EAAK;AAEhC,SAAAC,EAAU,MAAM;AACd,IAAIP,MACFK,EAAY,UAAU,IACtBF,EAAW,EAAI;AAAA,EACjB,GACC,CAACH,CAAO,CAAC,GAEZO,EAAU,MAAM;AACd,QAAIL,GAAS;AACL,YAAAM,IAAe,WAAW,MAAM;AACpC,QAAAH,EAAY,UAAU,IACtBF,EAAW,EAAK,GACUL,KAAA,QAAAA;AAAA,MAAA,GACzBjB,IAAiBoB,CAAQ;AAE5B,aAAO,MAAM;AACX,qBAAaO,CAAY;AAAA,MAAA;AAAA,IAE7B;AAAA,EACC,GAAA,CAACN,GAASJ,GAAyBG,CAAQ,CAAC,GAE/CM,EAAU,MAAM;AACd,QAAIP,KAAW,CAACE,KAAWG,EAAY,SAAS;AACxC,YAAAI,IAAY,WAAW,MAAM;AACX,QAAAZ,KAAA,QAAAA;AAAA,SACrBhB,CAAc;AAEjB,aAAO,MAAM;AACX,qBAAa4B,CAAS;AAAA,MAAA;AAAA,IAE1B;AAAA,EACC,GAAA,CAACT,GAASE,GAASL,CAAmB,CAAC,qBAGvCd,GAAU,EAAA,gBAAe,OAAM,aAAY,UAAS,eAAe,IACjE,UAAA;AAAA,IAAQa,KAAA,gBAAAc,EAACxB,KAAa,UAAKU,EAAA,CAAA;AAAA,IAC5B,gBAAAc;AAAA,MAACvB;AAAA,MAAA;AAAA,QACC,aAAY;AAAA,QACZ,UAAUe;AAAA,QACV,aAAaR;AAAA,QACb,eAAe;AAAA,QACf,SAAS,CAAC,CAACE;AAAA,QACX,YAAYI;AAAA,QACZ,OAAOD;AAAA,QACP,SAAS,CAACC;AAAA,QAET,UAAAL;AAAA,MAAA;AAAA,IACH;AAAA,EACF,EAAA,CAAA;AAEJ,GAEegB,IAAAC,EAAKnB,CAAkB;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { memo as a } from "react";
|
|
3
|
+
import p, { css as $, keyframes as m } from "styled-components";
|
|
4
|
+
import x from "../../ui/layout/flex-view.js";
|
|
5
|
+
import { getTheme as d } from "../../ui/theme/get-theme.js";
|
|
6
|
+
const f = d(), { colors: l } = f, u = (e) => {
|
|
7
|
+
const t = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);
|
|
8
|
+
return t && t[1] && t[2] && t[3] ? [parseInt(t[1], 16), parseInt(t[2], 16), parseInt(t[3], 16)] : null;
|
|
9
|
+
}, s = (e, t) => {
|
|
10
|
+
const n = u(e);
|
|
11
|
+
return n ? `rgba(${n.join(", ")}, ${t})` : null;
|
|
12
|
+
}, c = (e) => m`
|
|
13
|
+
0% {
|
|
14
|
+
box-shadow:
|
|
15
|
+
0 2px 5px ${e},
|
|
16
|
+
0 0 0 0 ${e},
|
|
17
|
+
0 0 0 2px ${s(e, 0.5)},
|
|
18
|
+
0 0 0 5px ${s(e, 0.5)};
|
|
19
|
+
}
|
|
20
|
+
100% {
|
|
21
|
+
box-shadow:
|
|
22
|
+
0 2px 5px ${s(e, 0.5)},
|
|
23
|
+
0 0 0 2px ${s(e, 0.5)},
|
|
24
|
+
0 0 0 5px ${s(e, 0.5)},
|
|
25
|
+
0 0 0 10px ${s(e, 0)};
|
|
26
|
+
}
|
|
27
|
+
`, b = p.div`
|
|
28
|
+
${({ $visible: e, $borderRadius: t, $color: n }) => e && $`
|
|
29
|
+
animation: ${c(n)} 1s linear infinite;
|
|
30
|
+
background: transparent;
|
|
31
|
+
border-radius: ${t}px;
|
|
32
|
+
z-index: 1;
|
|
33
|
+
`};
|
|
34
|
+
`, g = ({
|
|
35
|
+
children: e,
|
|
36
|
+
visible: t = !1,
|
|
37
|
+
color: n = "YELLOW_1",
|
|
38
|
+
borderRadius: i = 24,
|
|
39
|
+
...o
|
|
40
|
+
}) => /* @__PURE__ */ r(x, { $position: "relative", $alignItems: "center", $justifyContent: "center", children: /* @__PURE__ */ r(b, { $visible: t, $color: l[n], $borderRadius: i, ...o, children: e }) }), w = a(g);
|
|
41
|
+
export {
|
|
42
|
+
w as default
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=ripple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ripple.js","sources":["../../../../src/features/class-timer/animations/ripple.tsx"],"sourcesContent":["import type { TColorNames } from '../../ui/types';\n\nimport { memo, type ReactNode } from 'react';\nimport styled, { keyframes, css } from 'styled-components';\n\nimport FlexView from '../../ui/layout/flex-view';\nimport { getTheme } from '../../ui/theme/get-theme';\n\nconst theme = getTheme();\nconst { colors: COLORS } = theme;\n\nconst toRGB = (hex: string): number[] | null => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n\n return result && result[1] && result[2] && result[3]\n ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]\n : null;\n};\n\nconst toRGBA = (hex: string, alpha: number): string | null => {\n const rgb = toRGB(hex);\n\n return rgb ? `rgba(${rgb.join(', ')}, ${alpha})` : null;\n};\n\nconst pulse = (color: string) => keyframes`\n 0% {\n box-shadow: \n 0 2px 5px ${color},\n 0 0 0 0 ${color},\n 0 0 0 2px ${toRGBA(color, 0.5)},\n 0 0 0 5px ${toRGBA(color, 0.5)};\n }\n 100% {\n box-shadow:\n 0 2px 5px ${toRGBA(color, 0.5)},\n 0 0 0 2px ${toRGBA(color, 0.5)},\n 0 0 0 5px ${toRGBA(color, 0.5)},\n 0 0 0 10px ${toRGBA(color, 0)};\n }\n`;\n\ninterface PulseProps {\n $visible: boolean;\n $borderRadius: number;\n $color: string;\n}\n\nconst Pulse = styled.div<PulseProps>`\n ${({ $visible, $borderRadius, $color }) =>\n $visible &&\n css`\n animation: ${pulse($color)} 1s linear infinite;\n background: transparent;\n border-radius: ${$borderRadius}px;\n z-index: 1;\n `};\n`;\n\ninterface PulsatingProps {\n children: ReactNode;\n visible?: boolean;\n color?: TColorNames;\n borderRadius?: number;\n}\n\nconst Pulsating = ({\n children,\n visible = false,\n color = 'YELLOW_1',\n borderRadius = 24,\n ...other\n}: PulsatingProps) => (\n <FlexView $position=\"relative\" $alignItems=\"center\" $justifyContent=\"center\">\n <Pulse $visible={visible} $color={COLORS[color]} $borderRadius={borderRadius} {...other}>\n {children}\n </Pulse>\n </FlexView>\n);\n\nexport default memo(Pulsating);\n"],"names":["theme","getTheme","COLORS","toRGB","hex","result","toRGBA","alpha","rgb","pulse","color","keyframes","Pulse","styled","$visible","$borderRadius","$color","css","Pulsating","children","visible","borderRadius","other","jsx","FlexView","Ripple","memo"],"mappings":";;;;;AAQA,MAAMA,IAAQC,EAAS,GACjB,EAAE,QAAQC,EAAW,IAAAF,GAErBG,IAAQ,CAACC,MAAiC;AACxC,QAAAC,IAAS,4CAA4C,KAAKD,CAAG;AAEnE,SAAOC,KAAUA,EAAO,CAAC,KAAKA,EAAO,CAAC,KAAKA,EAAO,CAAC,IAC/C,CAAC,SAASA,EAAO,CAAC,GAAG,EAAE,GAAG,SAASA,EAAO,CAAC,GAAG,EAAE,GAAG,SAASA,EAAO,CAAC,GAAG,EAAE,CAAC,IAC1E;AACN,GAEMC,IAAS,CAACF,GAAaG,MAAiC;AACtD,QAAAC,IAAML,EAAMC,CAAG;AAEd,SAAAI,IAAM,QAAQA,EAAI,KAAK,IAAI,CAAC,KAAKD,CAAK,MAAM;AACrD,GAEME,IAAQ,CAACC,MAAkBC;AAAA;AAAA;AAAA,kBAGfD,CAAK;AAAA,gBACPA,CAAK;AAAA,kBACHJ,EAAOI,GAAO,GAAG,CAAC;AAAA,kBAClBJ,EAAOI,GAAO,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA,kBAIlBJ,EAAOI,GAAO,GAAG,CAAC;AAAA,kBAClBJ,EAAOI,GAAO,GAAG,CAAC;AAAA,kBAClBJ,EAAOI,GAAO,GAAG,CAAC;AAAA,mBACjBJ,EAAOI,GAAO,CAAC,CAAC;AAAA;AAAA,GAU7BE,IAAQC,EAAO;AAAA,IACjB,CAAC,EAAE,UAAAC,GAAU,eAAAC,GAAe,QAAAC,QAC5BF,KACAG;AAAA,mBACeR,EAAMO,CAAM,CAAC;AAAA;AAAA,uBAETD,CAAa;AAAA;AAAA,KAE/B;AAAA,GAUCG,IAAY,CAAC;AAAA,EACjB,UAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,OAAAV,IAAQ;AAAA,EACR,cAAAW,IAAe;AAAA,EACf,GAAGC;AACL,MACE,gBAAAC,EAACC,KAAS,WAAU,YAAW,aAAY,UAAS,iBAAgB,UAClE,UAAC,gBAAAD,EAAAX,GAAA,EAAM,UAAUQ,GAAS,QAAQlB,EAAOQ,CAAK,GAAG,eAAeW,GAAe,GAAGC,GAC/E,UAAAH,EACH,CAAA,EACF,CAAA,GAGaM,IAAAC,EAAKR,CAAS;"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as l, jsxs as F } from "react/jsx-runtime";
|
|
2
|
+
import { memo as Y, useMemo as f, useState as $, useCallback as x, useEffect as S, useRef as q } from "react";
|
|
3
|
+
import z from "../../assets/line-icons/icons/clock2.js";
|
|
4
|
+
import B from "../hooks/use-visibility-change.js";
|
|
5
|
+
import I from "../ui/layout/flex-view.js";
|
|
6
|
+
import H from "./animate.js";
|
|
7
|
+
import J from "./animations/ripple.js";
|
|
8
|
+
import K from "./clock.js";
|
|
9
|
+
import { START_TIMER as P, getClockColor as Q, ANIMATION_TIME as A, LAST_FIVE as U, IconWrapper as Z } from "./constants.js";
|
|
10
|
+
import ee from "./timer.js";
|
|
11
|
+
const te = (N) => {
|
|
12
|
+
const {
|
|
13
|
+
classDuration: e,
|
|
14
|
+
classStartedTime: r = 0,
|
|
15
|
+
extendedTime: t = 0,
|
|
16
|
+
ongoing: v,
|
|
17
|
+
onComplete: o,
|
|
18
|
+
onExtendClass: O,
|
|
19
|
+
onExtendedTimeStart: h,
|
|
20
|
+
showExtendIcon: V = !1,
|
|
21
|
+
updateWithExtendedTime: c = !1
|
|
22
|
+
} = N, d = (+/* @__PURE__ */ new Date() - +r) / 1e3, m = B(), k = f(() => t ? Math.floor(e - d) <= t * 60 : !1, [e, t, d]), [a, X] = $(k), u = f(() => {
|
|
23
|
+
const n = (+/* @__PURE__ */ new Date() - +r) / 1e3, p = Math.floor(e - n);
|
|
24
|
+
return c || !t || p <= t * 60 ? e : e - t * 60;
|
|
25
|
+
}, [e, t, r, c]), [s, R] = $(u), w = f(() => s + +r / 1e3, [s, r]), C = f(() => !!(d >= s - P || a || c && t), [d, s, a, c, t]), [b, D] = $(!1), T = Math.floor(s - d), [_, M] = $(C), G = Q({
|
|
26
|
+
remainingTime: T,
|
|
27
|
+
updateWithExtendedTime: c,
|
|
28
|
+
extendedTime: t,
|
|
29
|
+
extendedTimeStarted: a
|
|
30
|
+
}), g = x(() => {
|
|
31
|
+
X(!0), R(u), h == null || h();
|
|
32
|
+
}, [u, h]), E = x(() => {
|
|
33
|
+
D(!0);
|
|
34
|
+
}, []), y = f(
|
|
35
|
+
() => [
|
|
36
|
+
{
|
|
37
|
+
at: A.LAST_TEN,
|
|
38
|
+
callback: E,
|
|
39
|
+
id: "rem-10min"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
at: A.LAST_FIVE,
|
|
43
|
+
callback: E,
|
|
44
|
+
id: "rem-5min"
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
[E]
|
|
48
|
+
), W = x(() => {
|
|
49
|
+
if (t && !a && !c) {
|
|
50
|
+
g();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
o == null || o();
|
|
54
|
+
}, [
|
|
55
|
+
t,
|
|
56
|
+
a,
|
|
57
|
+
o,
|
|
58
|
+
g,
|
|
59
|
+
c
|
|
60
|
+
]);
|
|
61
|
+
S(() => {
|
|
62
|
+
const n = +/* @__PURE__ */ new Date() / 1e3 >= +r / 1e3 + e && e;
|
|
63
|
+
m && n && (o == null || o());
|
|
64
|
+
}, [e, r, m, o]), S(() => {
|
|
65
|
+
e && R(u);
|
|
66
|
+
}, [e, u]), S(() => {
|
|
67
|
+
m && k && !a && g();
|
|
68
|
+
}, [m, g, a, k]), S(() => {
|
|
69
|
+
s && r && m && M(C);
|
|
70
|
+
}, [r, s, C, m]);
|
|
71
|
+
const L = q(/* @__PURE__ */ new Set()), i = f(
|
|
72
|
+
() => y.filter((n) => {
|
|
73
|
+
const p = n.id || `multi-reminder-${n.at}`;
|
|
74
|
+
return !L.current.has(p) && T >= n.at;
|
|
75
|
+
}).sort((n, p) => p.at - n.at)[0],
|
|
76
|
+
[y, T]
|
|
77
|
+
), j = x(() => {
|
|
78
|
+
if (!i) return;
|
|
79
|
+
const n = i.id || `multi-reminder-${i.at}`;
|
|
80
|
+
L.current.add(n), typeof i.callback == "function" && i.callback();
|
|
81
|
+
}, [i]);
|
|
82
|
+
return !v || d >= 0 && T <= 0 ? null : /* @__PURE__ */ l(I, { $flexDirection: "row", $alignItems: "center", children: /* @__PURE__ */ F(I, { $position: "relative", $flexDirection: "row", $alignItems: "center", children: [
|
|
83
|
+
/* @__PURE__ */ l(
|
|
84
|
+
H,
|
|
85
|
+
{
|
|
86
|
+
animateClock: b,
|
|
87
|
+
classStartedTime: +r,
|
|
88
|
+
duration: s,
|
|
89
|
+
onExtendClass: O,
|
|
90
|
+
setAnimateClock: D,
|
|
91
|
+
setStartTimer: M,
|
|
92
|
+
showExtendIcon: !a && V
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
/* @__PURE__ */ l(
|
|
96
|
+
J,
|
|
97
|
+
{
|
|
98
|
+
color: T <= U ? "ORANGE_3" : "YELLOW_3",
|
|
99
|
+
visible: !b && _,
|
|
100
|
+
children: /* @__PURE__ */ F(
|
|
101
|
+
I,
|
|
102
|
+
{
|
|
103
|
+
$flexDirection: "row",
|
|
104
|
+
$alignItems: "center",
|
|
105
|
+
$background: "GREY_1",
|
|
106
|
+
$borderRadiusX: 1.25,
|
|
107
|
+
$gutterX: 0.5,
|
|
108
|
+
$gapX: 0.25,
|
|
109
|
+
$flexGapX: 0.25,
|
|
110
|
+
$position: "relative",
|
|
111
|
+
children: [
|
|
112
|
+
/* @__PURE__ */ l(Z, { $iconColor: G, children: /* @__PURE__ */ l(z, {}) }),
|
|
113
|
+
m && (_ ? /* @__PURE__ */ l(
|
|
114
|
+
ee,
|
|
115
|
+
{
|
|
116
|
+
endTime: w,
|
|
117
|
+
onComplete: W,
|
|
118
|
+
reminder: i == null ? void 0 : i.at,
|
|
119
|
+
onReminder: j
|
|
120
|
+
},
|
|
121
|
+
w
|
|
122
|
+
) : /* @__PURE__ */ l(
|
|
123
|
+
K,
|
|
124
|
+
{
|
|
125
|
+
completionTime: e - A.LAST_TEN,
|
|
126
|
+
onComplete: E,
|
|
127
|
+
startedOn: new Date(r)
|
|
128
|
+
}
|
|
129
|
+
))
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
] }) });
|
|
136
|
+
}, ue = Y(te);
|
|
137
|
+
export {
|
|
138
|
+
ue as default
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=class-timer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-timer.js","sources":["../../../src/features/class-timer/class-timer.tsx"],"sourcesContent":["import type { IClassTimeProps, MultiReminder } from './class-time-types';\n\nimport { useState, useCallback, useEffect, useMemo, useRef, memo } from 'react';\n\nimport Clock2Icon from '../../assets/line-icons/icons/clock2';\nimport useVisibilityChange from '../hooks/use-visibility-change';\nimport FlexView from '../ui/layout/flex-view';\nimport Animate from './animate';\nimport Ripple from './animations/ripple';\nimport Clock from './clock';\nimport { ANIMATION_TIME, getClockColor, IconWrapper, LAST_FIVE, START_TIMER } from './constants';\nimport Timer from './timer';\n\nconst ClassTime = (props: IClassTimeProps) => {\n const {\n classDuration,\n classStartedTime = 0,\n extendedTime = 0,\n ongoing,\n onComplete,\n onExtendClass,\n onExtendedTimeStart,\n showExtendIcon = false,\n updateWithExtendedTime = false,\n } = props;\n\n const elapsedTime = (+new Date() - +classStartedTime) / 1000;\n const isTabActive = useVisibilityChange();\n\n const hasExtendedTimeStarted = useMemo(() => {\n if (!extendedTime) return false;\n\n const orgRemainingTime = Math.floor(classDuration - elapsedTime);\n\n return orgRemainingTime <= extendedTime * 60;\n }, [classDuration, extendedTime, elapsedTime]);\n\n const [extendedTimeStarted, setExtendedTimeStarted] = useState(hasExtendedTimeStarted);\n\n const computedDuration = useMemo(() => {\n const elapsedT = (+new Date() - +classStartedTime) / 1000;\n const remainingT = Math.floor(classDuration - elapsedT);\n\n if (updateWithExtendedTime || !extendedTime || remainingT <= extendedTime * 60)\n return classDuration;\n\n return classDuration - extendedTime * 60;\n }, [classDuration, extendedTime, classStartedTime, updateWithExtendedTime]);\n\n const [duration, setDuration] = useState(computedDuration);\n const endTime = useMemo(() => duration + +classStartedTime / 1000, [duration, classStartedTime]);\n\n const canStartTimer = useMemo(() => {\n return !!(\n elapsedTime >= duration - START_TIMER ||\n extendedTimeStarted ||\n (updateWithExtendedTime && extendedTime)\n );\n }, [elapsedTime, duration, extendedTimeStarted, updateWithExtendedTime, extendedTime]);\n\n const [animateClock, setAnimateClock] = useState(false);\n const remainingTime = Math.floor(duration - elapsedTime); // in seconds\n const [startTimer, setStartTimer] = useState(canStartTimer);\n const clockColor = getClockColor({\n remainingTime,\n updateWithExtendedTime,\n extendedTime,\n extendedTimeStarted,\n });\n\n const handleStartExtendedTime = useCallback(() => {\n setExtendedTimeStarted(true);\n setDuration(computedDuration);\n onExtendedTimeStart?.();\n }, [computedDuration, onExtendedTimeStart]);\n\n const handleStartAnimation = useCallback(() => {\n setAnimateClock(true);\n }, []);\n\n const animationReminders = useMemo(\n () => [\n {\n at: ANIMATION_TIME.LAST_TEN,\n callback: handleStartAnimation,\n id: 'rem-10min',\n },\n\n {\n at: ANIMATION_TIME.LAST_FIVE,\n callback: handleStartAnimation,\n id: 'rem-5min',\n },\n ],\n [handleStartAnimation],\n );\n\n const handleTimerComplete = useCallback(() => {\n if (extendedTime && !extendedTimeStarted && !updateWithExtendedTime) {\n handleStartExtendedTime();\n\n return;\n }\n onComplete?.();\n }, [\n extendedTime,\n extendedTimeStarted,\n onComplete,\n handleStartExtendedTime,\n updateWithExtendedTime,\n ]);\n\n useEffect(() => {\n const isClassCompleted =\n +new Date() / 1000 >= +classStartedTime / 1000 + classDuration && classDuration;\n\n if (isTabActive && isClassCompleted) {\n onComplete?.();\n }\n }, [classDuration, classStartedTime, isTabActive, onComplete]);\n\n useEffect(() => {\n if (classDuration) {\n setDuration(computedDuration);\n }\n }, [classDuration, computedDuration]);\n\n useEffect(() => {\n if (isTabActive && hasExtendedTimeStarted && !extendedTimeStarted) {\n handleStartExtendedTime();\n }\n }, [isTabActive, handleStartExtendedTime, extendedTimeStarted, hasExtendedTimeStarted]);\n\n useEffect(() => {\n if (duration && classStartedTime && isTabActive) {\n setStartTimer(canStartTimer);\n }\n }, [classStartedTime, duration, canStartTimer, isTabActive]);\n\n const firedReminders = useRef<Set<string>>(new Set());\n const nextReminder = useMemo(\n () =>\n animationReminders\n .filter((r: MultiReminder) => {\n const key = r.id || `multi-reminder-${r.at}`;\n const alreadyFired = firedReminders.current.has(key);\n\n return !alreadyFired && remainingTime >= r.at;\n })\n .sort((a: { at: number }, b: { at: number }) => b.at - a.at)[0],\n [animationReminders, remainingTime],\n );\n\n const handleMultiReminder = useCallback(() => {\n if (!nextReminder) return;\n\n const key = nextReminder.id || `multi-reminder-${nextReminder.at}`;\n\n firedReminders.current.add(key);\n\n if (typeof nextReminder.callback === 'function') {\n nextReminder.callback();\n }\n }, [nextReminder]);\n\n if (!ongoing || (elapsedTime >= 0 && remainingTime <= 0)) {\n return null;\n }\n\n return (\n <FlexView $flexDirection=\"row\" $alignItems=\"center\">\n <FlexView $position=\"relative\" $flexDirection=\"row\" $alignItems=\"center\">\n <Animate\n animateClock={animateClock}\n classStartedTime={+classStartedTime}\n duration={duration}\n onExtendClass={onExtendClass}\n setAnimateClock={setAnimateClock}\n setStartTimer={setStartTimer}\n showExtendIcon={!extendedTimeStarted && showExtendIcon}\n />\n <Ripple\n color={remainingTime <= LAST_FIVE ? 'ORANGE_3' : 'YELLOW_3'}\n visible={!animateClock && startTimer}\n >\n <FlexView\n $flexDirection=\"row\"\n $alignItems=\"center\"\n $background=\"GREY_1\"\n $borderRadiusX={1.25}\n $gutterX={0.5}\n $gapX={0.25}\n $flexGapX={0.25}\n $position=\"relative\"\n >\n <IconWrapper $iconColor={clockColor}>\n <Clock2Icon />\n </IconWrapper>\n {isTabActive &&\n (startTimer ? (\n <Timer\n endTime={endTime}\n key={endTime}\n onComplete={handleTimerComplete}\n reminder={nextReminder?.at}\n onReminder={handleMultiReminder}\n />\n ) : (\n <Clock\n completionTime={classDuration - ANIMATION_TIME.LAST_TEN}\n onComplete={handleStartAnimation}\n startedOn={new Date(classStartedTime)}\n />\n ))}\n </FlexView>\n </Ripple>\n </FlexView>\n </FlexView>\n );\n};\n\nexport default memo(ClassTime);\n"],"names":["ClassTime","props","classDuration","classStartedTime","extendedTime","ongoing","onComplete","onExtendClass","onExtendedTimeStart","showExtendIcon","updateWithExtendedTime","elapsedTime","isTabActive","useVisibilityChange","hasExtendedTimeStarted","useMemo","extendedTimeStarted","setExtendedTimeStarted","useState","computedDuration","elapsedT","remainingT","duration","setDuration","endTime","canStartTimer","START_TIMER","animateClock","setAnimateClock","remainingTime","startTimer","setStartTimer","clockColor","getClockColor","handleStartExtendedTime","useCallback","handleStartAnimation","animationReminders","ANIMATION_TIME","handleTimerComplete","useEffect","isClassCompleted","firedReminders","useRef","nextReminder","r","key","a","b","handleMultiReminder","jsx","FlexView","jsxs","Animate","Ripple","LAST_FIVE","IconWrapper","Clock2Icon","Timer","Clock","classTimer","memo"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as d } from "react/jsx-runtime";
|
|
2
|
+
import { memo as w, useState as E, useRef as m, useCallback as $, useEffect as s } from "react";
|
|
3
|
+
import b from "../ui/text/text.js";
|
|
4
|
+
import { formatTimeInHHMMSS as h } from "../utils/utils.js";
|
|
5
|
+
import { getTime as f, TIMEOUT_INTERVAL as i } from "./constants.js";
|
|
6
|
+
const k = ({
|
|
7
|
+
completionTime: t = null,
|
|
8
|
+
onComplete: o = () => {
|
|
9
|
+
},
|
|
10
|
+
startedOn: u,
|
|
11
|
+
textVariant: a = "ab2-bold",
|
|
12
|
+
textColor: p
|
|
13
|
+
}) => {
|
|
14
|
+
const [e, T] = E(f(u)), r = m(null), l = h(e), n = m(null), c = $(() => {
|
|
15
|
+
performance.now() - (n.current || 0) >= 1e3 && (T(f(u)), n.current = performance.now()), r.current = setTimeout(c, i);
|
|
16
|
+
}, [u]);
|
|
17
|
+
return s(() => {
|
|
18
|
+
t && e >= t && e <= t + 5 && (r.current && (clearTimeout(r.current), r.current = null), o());
|
|
19
|
+
}, [t, e, o]), s(() => (r.current && (clearTimeout(r.current), r.current = null), n.current === null && (n.current = performance.now()), r.current = setTimeout(c, i), () => {
|
|
20
|
+
r.current && clearTimeout(r.current);
|
|
21
|
+
}), [c]), e < 0 ? null : /* @__PURE__ */ d(b, { $width: l.length > 5 ? 71 : 57, $renderAs: a, $color: p, children: l });
|
|
22
|
+
}, C = w(k);
|
|
23
|
+
export {
|
|
24
|
+
C as default
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=clock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.js","sources":["../../../src/features/class-timer/clock.tsx"],"sourcesContent":["import type { TColorNames, TTextVariants } from '../ui/types';\n\nimport { useState, useEffect, useCallback, useRef, memo } from 'react';\n\nimport Text from '../ui/text/text';\nimport { formatTimeInHHMMSS } from '../utils/utils';\nimport { getTime, TIMEOUT_INTERVAL } from './constants';\n\ninterface IClockProps {\n completionTime?: number | null;\n onComplete?: () => void;\n startedOn: Date;\n textVariant?: TTextVariants;\n textColor?: TColorNames;\n}\n\nconst Clock = ({\n completionTime = null,\n onComplete = () => {},\n startedOn,\n textVariant = 'ab2-bold',\n textColor,\n}: IClockProps) => {\n const [elapsedTime, setElapsedTime] = useState(getTime(startedOn));\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const formattedTime = formatTimeInHHMMSS(elapsedTime);\n const start = useRef<number | null>(null);\n const timer = useCallback(() => {\n const timestamp = performance.now();\n\n const elapsed = timestamp - (start.current || 0);\n\n if (elapsed >= 1000) {\n setElapsedTime(getTime(startedOn));\n\n start.current = performance.now();\n }\n\n timerRef.current = setTimeout(timer, TIMEOUT_INTERVAL);\n }, [startedOn]);\n\n useEffect(() => {\n if (completionTime && elapsedTime >= completionTime && elapsedTime <= completionTime + 5) {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n\n onComplete();\n }\n }, [completionTime, elapsedTime, onComplete]);\n\n useEffect(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n\n if (start.current === null) {\n start.current = performance.now();\n }\n\n timerRef.current = setTimeout(timer, TIMEOUT_INTERVAL);\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n };\n }, [timer]);\n\n if (elapsedTime < 0) return null;\n\n return (\n <Text $width={formattedTime.length > 5 ? 71 : 57} $renderAs={textVariant} $color={textColor}>\n {formattedTime}\n </Text>\n );\n};\n\nexport default memo(Clock);\n"],"names":["Clock","completionTime","onComplete","startedOn","textVariant","textColor","elapsedTime","setElapsedTime","useState","getTime","timerRef","useRef","formattedTime","formatTimeInHHMMSS","start","timer","useCallback","TIMEOUT_INTERVAL","useEffect","jsx","Text","Clock$1","memo"],"mappings":";;;;;AAgBA,MAAMA,IAAQ,CAAC;AAAA,EACb,gBAAAC,IAAiB;AAAA,EACjB,YAAAC,IAAa,MAAM;AAAA,EAAC;AAAA,EACpB,WAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,WAAAC;AACF,MAAmB;AACjB,QAAM,CAACC,GAAaC,CAAc,IAAIC,EAASC,EAAQN,CAAS,CAAC,GAC3DO,IAAWC,EAA8B,IAAI,GAC7CC,IAAgBC,EAAmBP,CAAW,GAC9CQ,IAAQH,EAAsB,IAAI,GAClCI,IAAQC,EAAY,MAAM;AAK9B,IAJkB,YAAY,SAEDF,EAAM,WAAW,MAE/B,QACEP,EAAAE,EAAQN,CAAS,CAAC,GAE3BW,EAAA,UAAU,YAAY,QAGrBJ,EAAA,UAAU,WAAWK,GAAOE,CAAgB;AAAA,EAAA,GACpD,CAACd,CAAS,CAAC;AAgCV,SA9BJe,EAAU,MAAM;AACd,IAAIjB,KAAkBK,KAAeL,KAAkBK,KAAeL,IAAiB,MACjFS,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU,OAGVR;EAEZ,GAAA,CAACD,GAAgBK,GAAaJ,CAAU,CAAC,GAE5CgB,EAAU,OACJR,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU,OAGjBI,EAAM,YAAY,SACdA,EAAA,UAAU,YAAY,QAGrBJ,EAAA,UAAU,WAAWK,GAAOE,CAAgB,GAE9C,MAAM;AACX,IAAIP,EAAS,WACX,aAAaA,EAAS,OAAO;AAAA,EAC/B,IAED,CAACK,CAAK,CAAC,GAENT,IAAc,IAAU,OAGzB,gBAAAa,EAAAC,GAAA,EAAK,QAAQR,EAAc,SAAS,IAAI,KAAK,IAAI,WAAWR,GAAa,QAAQC,GAC/E,UACHO,EAAA,CAAA;AAEJ,GAEeS,IAAAC,EAAKtB,CAAK;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import c from "styled-components";
|
|
2
|
+
import n from "../ui/layout/flex-view.js";
|
|
3
|
+
const s = c(n)`
|
|
4
|
+
svg {
|
|
5
|
+
color: ${(o) => o.theme.colors[o.$iconColor]};
|
|
6
|
+
}
|
|
7
|
+
`, t = 60 * 10, e = 60 * 5, L = {
|
|
8
|
+
LAST_TEN: t + 2,
|
|
9
|
+
LAST_FIVE: e + 2
|
|
10
|
+
}, A = 2e3, l = 1500, i = 250, m = ({
|
|
11
|
+
remainingTime: o,
|
|
12
|
+
updateWithExtendedTime: r,
|
|
13
|
+
extendedTime: T,
|
|
14
|
+
extendedTimeStarted: E
|
|
15
|
+
}) => o <= e ? "ORANGE_3" : o <= t || r && T || E ? "YELLOW_3" : "BLACK_3", M = (o) => Math.floor(((/* @__PURE__ */ new Date()).getTime() - o.getTime()) / 1e3);
|
|
16
|
+
export {
|
|
17
|
+
L as ANIMATION_TIME,
|
|
18
|
+
l as EXTEND_IDLE,
|
|
19
|
+
s as IconWrapper,
|
|
20
|
+
e as LAST_FIVE,
|
|
21
|
+
t as START_TIMER,
|
|
22
|
+
i as TIMEOUT_INTERVAL,
|
|
23
|
+
A as TIME_LEFT_IDLE,
|
|
24
|
+
m as getClockColor,
|
|
25
|
+
M as getTime
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../src/features/class-timer/constants.ts"],"sourcesContent":["import type { TColorNames } from '../ui/types';\n\nimport styled from 'styled-components';\n\nimport FlexView from '../ui/layout/flex-view';\n\nconst IconWrapper = styled(FlexView)<{ $iconColor: TColorNames }>`\n svg {\n color: ${props => props.theme.colors[props.$iconColor]};\n }\n`;\n\nconst START_TIMER = 60 * 10; // 10 minutes\nconst LAST_FIVE = 60 * 5; // 5 minutes\nconst ANIMATION_TIME = {\n LAST_TEN: START_TIMER + 2,\n LAST_FIVE: LAST_FIVE + 2,\n};\n\nconst TIME_LEFT_IDLE = 2000;\nconst EXTEND_IDLE = 1500;\nconst TIMEOUT_INTERVAL = 250;\n\ninterface IClockColorParams {\n remainingTime: number;\n updateWithExtendedTime: boolean;\n extendedTime: number;\n extendedTimeStarted: boolean;\n}\n\nconst getClockColor = ({\n remainingTime,\n updateWithExtendedTime,\n extendedTime,\n extendedTimeStarted,\n}: IClockColorParams): TColorNames => {\n if (remainingTime <= LAST_FIVE) return 'ORANGE_3';\n\n if (\n remainingTime <= START_TIMER ||\n (updateWithExtendedTime && extendedTime) ||\n extendedTimeStarted\n )\n return 'YELLOW_3';\n\n return 'BLACK_3';\n};\n\nconst getTime = (startedOn: Date): number => {\n return Math.floor((new Date().getTime() - startedOn.getTime()) / 1000);\n};\n\nexport {\n getClockColor,\n getTime,\n IconWrapper,\n ANIMATION_TIME,\n START_TIMER,\n LAST_FIVE,\n TIME_LEFT_IDLE,\n EXTEND_IDLE,\n TIMEOUT_INTERVAL,\n};\n"],"names":["IconWrapper","styled","FlexView","props","START_TIMER","LAST_FIVE","ANIMATION_TIME","TIME_LEFT_IDLE","EXTEND_IDLE","TIMEOUT_INTERVAL","getClockColor","remainingTime","updateWithExtendedTime","extendedTime","extendedTimeStarted","getTime","startedOn"],"mappings":";;AAMM,MAAAA,IAAcC,EAAOC,CAAQ;AAAA;AAAA,aAEtB,OAASC,EAAM,MAAM,OAAOA,EAAM,UAAU,CAAC;AAAA;AAAA,GAIpDC,IAAc,KAAK,IACnBC,IAAY,KAAK,GACjBC,IAAiB;AAAA,EACrB,UAAUF,IAAc;AAAA,EACxB,WAAWC,IAAY;AACzB,GAEME,IAAiB,KACjBC,IAAc,MACdC,IAAmB,KASnBC,IAAgB,CAAC;AAAA,EACrB,eAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,qBAAAC;AACF,MACMH,KAAiBN,IAAkB,aAGrCM,KAAiBP,KAChBQ,KAA0BC,KAC3BC,IAEO,aAEF,WAGHC,IAAU,CAACC,MACR,KAAK,QAAO,oBAAI,KAAK,GAAE,YAAYA,EAAU,QAAQ,KAAK,GAAI;"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsxs as x, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { memo as I, useState as b, useRef as f, useCallback as A, useEffect as p } from "react";
|
|
3
|
+
import M from "styled-components";
|
|
4
|
+
import k from "../../assets/line-icons/icons/clock2.js";
|
|
5
|
+
import E from "../ui/layout/flex-view.js";
|
|
6
|
+
import $ from "../ui/text/text.js";
|
|
7
|
+
import { formatTimeInHHMMSS as R } from "../utils/utils.js";
|
|
8
|
+
import { TIMEOUT_INTERVAL as T, IconWrapper as X } from "./constants.js";
|
|
9
|
+
const D = M(E)`
|
|
10
|
+
border-radius: 20px;
|
|
11
|
+
position: relative;
|
|
12
|
+
z-index: 7;
|
|
13
|
+
gap: 8px;
|
|
14
|
+
`, L = ({
|
|
15
|
+
styledTimer: d = !1,
|
|
16
|
+
endTime: o,
|
|
17
|
+
onComplete: e,
|
|
18
|
+
onReminder: u,
|
|
19
|
+
reminder: a,
|
|
20
|
+
iconColor: h = "BLACK",
|
|
21
|
+
textColor: m = "BLACK",
|
|
22
|
+
textVariant: l = "ac3-black"
|
|
23
|
+
}) => {
|
|
24
|
+
const [t, g] = b(Math.ceil(o - Date.now() / 1e3)), r = f(null), c = f(null), s = A(() => {
|
|
25
|
+
if (performance.now() - (c.current || 0) >= 1e3) {
|
|
26
|
+
const w = Math.ceil(o - Date.now() / 1e3);
|
|
27
|
+
g(w), c.current = performance.now();
|
|
28
|
+
}
|
|
29
|
+
r.current = setTimeout(s, T);
|
|
30
|
+
}, [o]);
|
|
31
|
+
p(() => (r.current && (clearTimeout(r.current), r.current = null), c.current === null && (c.current = performance.now()), r.current = setTimeout(s, T), () => {
|
|
32
|
+
r.current && clearTimeout(r.current);
|
|
33
|
+
}), [s]), p(() => {
|
|
34
|
+
a && u && t === a && u(), t <= 0 && (r.current && (clearTimeout(r.current), r.current = null), e == null || e());
|
|
35
|
+
}, [a, u, e, t]);
|
|
36
|
+
const n = R(t);
|
|
37
|
+
return d ? /* @__PURE__ */ x(
|
|
38
|
+
D,
|
|
39
|
+
{
|
|
40
|
+
$flexDirection: "row",
|
|
41
|
+
$alignItems: "center",
|
|
42
|
+
$background: "GREY_1",
|
|
43
|
+
$borderRadiusX: 1.25,
|
|
44
|
+
$gutterX: 0.75,
|
|
45
|
+
$gapX: 0.15,
|
|
46
|
+
$flexGapX: 0.25,
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ i(X, { $iconColor: h, children: /* @__PURE__ */ i(k, {}) }),
|
|
49
|
+
/* @__PURE__ */ i(
|
|
50
|
+
$,
|
|
51
|
+
{
|
|
52
|
+
$width: n.length > 5 ? 71 : 57,
|
|
53
|
+
$renderAs: l,
|
|
54
|
+
$color: m,
|
|
55
|
+
children: n
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
) : /* @__PURE__ */ i($, { $width: n.length > 5 ? 71 : 57, $renderAs: l, $color: m, children: n });
|
|
61
|
+
}, z = I(L);
|
|
62
|
+
export {
|
|
63
|
+
z as default
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=timer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timer.js","sources":["../../../src/features/class-timer/timer.tsx"],"sourcesContent":["import type { TColorNames, TTextVariants } from '../ui/types';\n\nimport { memo, useCallback, useEffect, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport Clock2Icon from '../../assets/line-icons/icons/clock2';\nimport FlexView from '../ui/layout/flex-view';\nimport Text from '../ui/text/text';\nimport { formatTimeInHHMMSS } from '../utils/utils';\nimport { IconWrapper, TIMEOUT_INTERVAL } from './constants';\n\nconst TimeWrapper = styled(FlexView)`\n border-radius: 20px;\n position: relative;\n z-index: 7;\n gap: 8px;\n`;\n\ninterface ITimerProps {\n styledTimer?: boolean;\n endTime: number;\n onComplete?: () => void;\n onReminder?: () => void;\n reminder?: number;\n iconColor?: TColorNames;\n textColor?: TColorNames;\n textVariant?: TTextVariants;\n}\n\nconst Timer = ({\n styledTimer = false,\n endTime,\n onComplete,\n onReminder,\n reminder,\n iconColor = 'BLACK',\n textColor = 'BLACK',\n textVariant = 'ac3-black',\n}: ITimerProps) => {\n const [remainingTime, setRemainingTime] = useState(Math.ceil(endTime - Date.now() / 1000));\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const start = useRef<number | null>(null);\n const timer = useCallback(() => {\n const timestamp = performance.now();\n const elapsed = timestamp - (start.current || 0);\n\n if (elapsed >= 1000) {\n // only if 1s has elapsed\n const rt = Math.ceil(endTime - Date.now() / 1000);\n\n setRemainingTime(rt);\n start.current = performance.now();\n }\n\n timerRef.current = setTimeout(timer, TIMEOUT_INTERVAL);\n }, [endTime]);\n\n useEffect(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n\n if (start.current === null) {\n start.current = performance.now();\n }\n\n timerRef.current = setTimeout(timer, TIMEOUT_INTERVAL);\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n };\n }, [timer]);\n\n useEffect(() => {\n if (reminder && onReminder && remainingTime === reminder) {\n onReminder();\n }\n\n if (remainingTime <= 0) {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n onComplete?.();\n }\n }, [reminder, onReminder, onComplete, remainingTime]);\n const formattedTime = formatTimeInHHMMSS(remainingTime);\n\n if (styledTimer) {\n return (\n <TimeWrapper\n $flexDirection=\"row\"\n $alignItems=\"center\"\n $background=\"GREY_1\"\n $borderRadiusX={1.25}\n $gutterX={0.75}\n $gapX={0.15}\n $flexGapX={0.25}\n >\n <IconWrapper $iconColor={iconColor}>\n <Clock2Icon />\n </IconWrapper>\n <Text\n $width={formattedTime.length > 5 ? 71 : 57}\n $renderAs={textVariant}\n $color={textColor}\n >\n {formattedTime}\n </Text>\n </TimeWrapper>\n );\n }\n\n return (\n <Text $width={formattedTime.length > 5 ? 71 : 57} $renderAs={textVariant} $color={textColor}>\n {formattedTime}\n </Text>\n );\n};\n\nexport default memo(Timer);\n"],"names":["TimeWrapper","styled","FlexView","Timer","styledTimer","endTime","onComplete","onReminder","reminder","iconColor","textColor","textVariant","remainingTime","setRemainingTime","useState","timerRef","useRef","start","timer","useCallback","rt","TIMEOUT_INTERVAL","useEffect","formattedTime","formatTimeInHHMMSS","jsxs","jsx","IconWrapper","Clock2Icon","Text","Timer$1","memo"],"mappings":";;;;;;;;AAWA,MAAMA,IAAcC,EAAOC,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,GAkB7BC,IAAQ,CAAC;AAAA,EACb,aAAAC,IAAc;AAAA,EACd,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAC,IAAY;AAAA,EACZ,aAAAC,IAAc;AAChB,MAAmB;AACjB,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAAS,KAAK,KAAKT,IAAU,KAAK,QAAQ,GAAI,CAAC,GACnFU,IAAWC,EAA8B,IAAI,GAC7CC,IAAQD,EAAsB,IAAI,GAClCE,IAAQC,EAAY,MAAM;AAI9B,QAHkB,YAAY,SACDF,EAAM,WAAW,MAE/B,KAAM;AAEnB,YAAMG,IAAK,KAAK,KAAKf,IAAU,KAAK,IAAA,IAAQ,GAAI;AAEhD,MAAAQ,EAAiBO,CAAE,GACbH,EAAA,UAAU,YAAY;IAC9B;AAES,IAAAF,EAAA,UAAU,WAAWG,GAAOG,CAAgB;AAAA,EAAA,GACpD,CAAChB,CAAO,CAAC;AAEZ,EAAAiB,EAAU,OACJP,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU,OAGjBE,EAAM,YAAY,SACdA,EAAA,UAAU,YAAY,QAGrBF,EAAA,UAAU,WAAWG,GAAOG,CAAgB,GAE9C,MAAM;AACX,IAAIN,EAAS,WACX,aAAaA,EAAS,OAAO;AAAA,EAC/B,IAED,CAACG,CAAK,CAAC,GAEVI,EAAU,MAAM;AACV,IAAAd,KAAYD,KAAcK,MAAkBJ,KACnCD,KAGTK,KAAiB,MACfG,EAAS,YACX,aAAaA,EAAS,OAAO,GAC7BA,EAAS,UAAU,OAERT,KAAA,QAAAA;AAAA,KAEd,CAACE,GAAUD,GAAYD,GAAYM,CAAa,CAAC;AAC9C,QAAAW,IAAgBC,EAAmBZ,CAAa;AAEtD,SAAIR,IAEA,gBAAAqB;AAAA,IAACzB;AAAA,IAAA;AAAA,MACC,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,aAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,WAAW;AAAA,MAEX,UAAA;AAAA,QAAA,gBAAA0B,EAACC,GAAY,EAAA,YAAYlB,GACvB,UAAA,gBAAAiB,EAACE,IAAW,CAAA,GACd;AAAA,QACA,gBAAAF;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,QAAQN,EAAc,SAAS,IAAI,KAAK;AAAA,YACxC,WAAWZ;AAAA,YACX,QAAQD;AAAA,YAEP,UAAAa;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,IAMH,gBAAAG,EAAAG,GAAA,EAAK,QAAQN,EAAc,SAAS,IAAI,KAAK,IAAI,WAAWZ,GAAa,QAAQD,GAC/E,UACHa,EAAA,CAAA;AAEJ,GAEeO,IAAAC,EAAK5B,CAAK;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useState as n, useCallback as l, useEffect as a } from "react";
|
|
2
|
+
const o = () => {
|
|
3
|
+
const [t, e] = n(document.visibilityState === "visible"), i = l(() => {
|
|
4
|
+
const s = document.visibilityState === "visible";
|
|
5
|
+
e(s);
|
|
6
|
+
}, [e]);
|
|
7
|
+
return a(() => (document.addEventListener("visibilitychange", i), () => document.removeEventListener("visibilitychange", i)), [i]), t;
|
|
8
|
+
}, c = o;
|
|
9
|
+
export {
|
|
10
|
+
c as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=use-visibility-change.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-visibility-change.js","sources":["../../../src/features/hooks/use-visibility-change.tsx"],"sourcesContent":["import { useEffect, useState, useCallback } from 'react';\n\n/**\n * Custom hook to detect visibility change of the document.\n * Returns true if the document is visible, false otherwise.\n */\nconst useVisibilityChange = () => {\n const [isVisible, setIsVisible] = useState(document.visibilityState === 'visible');\n\n const onVisibilityChange = useCallback(() => {\n const isVisibleState = document.visibilityState === 'visible';\n\n setIsVisible(isVisibleState);\n }, [setIsVisible]);\n\n useEffect(() => {\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n return () => document.removeEventListener('visibilitychange', onVisibilityChange);\n }, [onVisibilityChange]);\n\n return isVisible;\n};\n\nexport default useVisibilityChange;\n"],"names":["useVisibilityChange","isVisible","setIsVisible","useState","onVisibilityChange","useCallback","isVisibleState","useEffect","useVisibilityChange$1"],"mappings":";AAMA,MAAMA,IAAsB,MAAM;AAChC,QAAM,CAACC,GAAWC,CAAY,IAAIC,EAAS,SAAS,oBAAoB,SAAS,GAE3EC,IAAqBC,EAAY,MAAM;AACrC,UAAAC,IAAiB,SAAS,oBAAoB;AAEpD,IAAAJ,EAAaI,CAAc;AAAA,EAAA,GAC1B,CAACJ,CAAY,CAAC;AAEjB,SAAAK,EAAU,OACC,SAAA,iBAAiB,oBAAoBH,CAAkB,GAEzD,MAAM,SAAS,oBAAoB,oBAAoBA,CAAkB,IAC/E,CAACA,CAAkB,CAAC,GAEhBH;AACT,GAEAO,IAAeR;"}
|
|
@@ -15,7 +15,10 @@ const _ = {
|
|
|
15
15
|
DESMOS_CALCULATOR: 2,
|
|
16
16
|
GOAL_CHAPTER_SHEETS_MENU: 4,
|
|
17
17
|
JOURNEY_OVERLAY: 1e3,
|
|
18
|
-
CHAPTER_COMPLETED_LOTTIE: 5
|
|
18
|
+
CHAPTER_COMPLETED_LOTTIE: 5,
|
|
19
|
+
EXTEND_CLASS_ANIMATION_1: 24,
|
|
20
|
+
EXTEND_CLASS_ANIMATION_2: 25,
|
|
21
|
+
EXTEND_CLASS_ANIMATION_3: 26
|
|
19
22
|
};
|
|
20
23
|
export {
|
|
21
24
|
_ as ZINDEX
|