@titan-design/react-ui 0.7.0 → 0.9.0
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/index.d.mts +112 -55
- package/dist/index.d.ts +112 -55
- package/dist/index.js +795 -501
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +795 -498
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-8u_4WbL-.d.mts → pages-D7hOD4Vj.d.mts} +17 -8
- package/dist/{pages-DaWiBOGa.d.ts → pages-DyEx-lBf.d.ts} +17 -8
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +691 -250
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +692 -251
- package/dist/pages.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +90 -0
- package/src/components/custom/CircularTimer/CircularTimer.test.tsx +62 -0
- package/src/components/custom/CircularTimer/CircularTimer.tsx +112 -0
- package/src/components/custom/CircularTimer/index.ts +1 -0
- package/src/components/custom/Workout/ExerciseIndicator.tsx +1 -1
- package/src/components/custom/Workout/FatigueMeter.stories.tsx +2 -2
- package/src/components/custom/Workout/FatigueMeter.test.tsx +12 -0
- package/src/components/custom/Workout/FatigueMeter.tsx +7 -3
- package/src/components/custom/Workout/README.md +70 -3
- package/src/components/custom/Workout/RestTimer.stories.tsx +132 -2
- package/src/components/custom/Workout/RestTimer.test.tsx +73 -0
- package/src/components/custom/Workout/RestTimer.tsx +141 -50
- package/src/components/custom/Workout/SetsRepsLoad.test.tsx +6 -0
- package/src/components/custom/Workout/SetsRepsLoad.tsx +15 -6
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +240 -65
- package/src/components/custom/Workout/TempoDisplay.test.tsx +61 -16
- package/src/components/custom/Workout/TempoDisplay.tsx +173 -60
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +152 -9
- package/src/components/custom/Workout/VelocityStrip.test.tsx +67 -3
- package/src/components/custom/Workout/VelocityStrip.tsx +323 -42
- package/src/components/custom/Workout/ZoneTrack.stories.tsx +2 -3
- package/src/components/custom/Workout/ZoneTrack.test.tsx +34 -0
- package/src/components/custom/Workout/ZoneTrack.tsx +91 -19
- package/src/components/custom/Workout/index.ts +1 -9
- package/src/components/custom/index.ts +1 -0
- package/src/components/ui/alert/Alert.stories.tsx +85 -2
- package/src/components/ui/alert/Alert.test.tsx +52 -0
- package/src/components/ui/alert/Alert.tsx +54 -20
- package/src/components/ui/progress/Progress.tsx +47 -22
- package/src/lab/north-star/LivePage.tsx +101 -0
- package/src/lab/north-star/LiveView.tsx +409 -0
- package/src/lab/north-star/LiveWallDashboard.stories.tsx +129 -0
- package/src/lab/north-star/RestView.tsx +140 -0
- package/src/lab/north-star/fixtures.ts +224 -0
- package/src/components/custom/Workout/TempoBar.stories.tsx +0 -95
- package/src/components/custom/Workout/TempoBar.test.tsx +0 -103
- package/src/components/custom/Workout/TempoBar.tsx +0 -215
package/dist/pages.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useMemo, useEffect, Fragment as Fragment$1, useSyncExternalStore, useCallback } from 'react';
|
|
2
|
-
import { Easing, Platform, View, Text,
|
|
2
|
+
import { Easing, Platform, View, Text, TextInput, Pressable, Animated, ScrollView } from 'react-native';
|
|
3
3
|
import { Fragment, jsx as jsx$1, jsxs as jsxs$1 } from 'react/jsx-runtime';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -33,6 +33,8 @@ var primitiveColors = {
|
|
|
33
33
|
900: "#111827"},
|
|
34
34
|
// Charcoal scale (dark backgrounds)
|
|
35
35
|
charcoal: {
|
|
36
|
+
0: "#6E6E6E",
|
|
37
|
+
100: "#4C4C4C",
|
|
36
38
|
200: "#3C3C3C",
|
|
37
39
|
300: "#2C2C2C",
|
|
38
40
|
400: "#1F1F1F",
|
|
@@ -74,6 +76,7 @@ var primitiveRamps = {
|
|
|
74
76
|
500: "#22A444",
|
|
75
77
|
600: "#298732"},
|
|
76
78
|
cyan: {
|
|
79
|
+
300: "#22D3EE",
|
|
77
80
|
// pin
|
|
78
81
|
400: "#01B5D1",
|
|
79
82
|
500: "#2697B7",
|
|
@@ -88,6 +91,7 @@ var primitiveRamps = {
|
|
|
88
91
|
// pin
|
|
89
92
|
600: "#1072CB"},
|
|
90
93
|
magenta: {
|
|
94
|
+
400: "#ED69C3",
|
|
91
95
|
600: "#BA2996"}
|
|
92
96
|
};
|
|
93
97
|
var sequentialEffort = [
|
|
@@ -604,8 +608,18 @@ var EXPANDED_ENCODED_PCT = 45;
|
|
|
604
608
|
var EXPANDED_HEIGHT = 60;
|
|
605
609
|
var FIXED_MAX_VELOCITY = 1.15;
|
|
606
610
|
var BARE_STUB_HEIGHT = 3;
|
|
611
|
+
var HERO_HEIGHT = 220;
|
|
612
|
+
var HERO_LABEL_HEADROOM = 20;
|
|
613
|
+
var HERO_BAR_GAP = 8;
|
|
614
|
+
var HERO_BAR_MAX_WIDTH = 120;
|
|
615
|
+
var HERO_LABEL_MIN_BAR_WIDTH = 30;
|
|
616
|
+
var HERO_BAR_RADIUS = 5;
|
|
617
|
+
var HERO_MIN_BAR_HEIGHT = 4;
|
|
618
|
+
var HERO_PENDING_COLOR = primitiveColors.charcoal[100];
|
|
619
|
+
var HERO_REFERENCE_COLOR = primitiveColors.charcoal[0];
|
|
620
|
+
var PEAK_HEADROOM = 1.06;
|
|
607
621
|
function scaleDenominator(scale, maxVelocity) {
|
|
608
|
-
return scale === "fixed" ? FIXED_MAX_VELOCITY : maxVelocity *
|
|
622
|
+
return scale === "fixed" ? FIXED_MAX_VELOCITY : maxVelocity * PEAK_HEADROOM;
|
|
609
623
|
}
|
|
610
624
|
function bareSlotHeight(slot, height, denom) {
|
|
611
625
|
if (slot.kind !== "rep" || denom <= 0) return BARE_STUB_HEIGHT;
|
|
@@ -631,6 +645,195 @@ function usePrefersReducedMotion() {
|
|
|
631
645
|
var ANIMATION_DURATION = 400;
|
|
632
646
|
var ANIMATION_EASING = Easing.bezier(0.22, 1, 0.36, 1);
|
|
633
647
|
var POP_EASING = Easing.bezier(0.34, 1.56, 0.64, 1);
|
|
648
|
+
function useLiveRepPop(active, liveRepIndex, liveVelocity, isNewPeak) {
|
|
649
|
+
const prefersReducedMotion = usePrefersReducedMotion();
|
|
650
|
+
const [liveScale] = useState(() => new Animated.Value(1));
|
|
651
|
+
useEffect(() => {
|
|
652
|
+
if (!active || liveRepIndex == null || liveVelocity == null) return;
|
|
653
|
+
if (prefersReducedMotion) {
|
|
654
|
+
liveScale.setValue(1);
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
if (isNewPeak) {
|
|
658
|
+
liveScale.setValue(1);
|
|
659
|
+
Animated.sequence([
|
|
660
|
+
Animated.timing(liveScale, {
|
|
661
|
+
toValue: 1.25,
|
|
662
|
+
duration: 150,
|
|
663
|
+
easing: Easing.out(Easing.quad),
|
|
664
|
+
useNativeDriver: true
|
|
665
|
+
}),
|
|
666
|
+
Animated.spring(liveScale, {
|
|
667
|
+
toValue: 1,
|
|
668
|
+
friction: 3,
|
|
669
|
+
tension: 140,
|
|
670
|
+
useNativeDriver: true
|
|
671
|
+
})
|
|
672
|
+
]).start();
|
|
673
|
+
} else {
|
|
674
|
+
liveScale.setValue(0.8);
|
|
675
|
+
Animated.timing(liveScale, {
|
|
676
|
+
toValue: 1,
|
|
677
|
+
duration: 300,
|
|
678
|
+
easing: POP_EASING,
|
|
679
|
+
useNativeDriver: true
|
|
680
|
+
}).start();
|
|
681
|
+
}
|
|
682
|
+
}, [active, liveRepIndex, liveVelocity, isNewPeak, prefersReducedMotion, liveScale]);
|
|
683
|
+
return liveScale;
|
|
684
|
+
}
|
|
685
|
+
function HeroVelocityChart({
|
|
686
|
+
doneVelocities,
|
|
687
|
+
barColorFor,
|
|
688
|
+
scaleDenom,
|
|
689
|
+
referenceVelocity,
|
|
690
|
+
liveRepIndex,
|
|
691
|
+
isNewPeak,
|
|
692
|
+
targetReps,
|
|
693
|
+
height,
|
|
694
|
+
className,
|
|
695
|
+
viewProps
|
|
696
|
+
}) {
|
|
697
|
+
const liveVelocity = liveRepIndex != null ? doneVelocities[liveRepIndex] : void 0;
|
|
698
|
+
const liveScale = useLiveRepPop(true, liveRepIndex, liveVelocity, isNewPeak);
|
|
699
|
+
const [plotW, setPlotW] = useState(0);
|
|
700
|
+
const onPlotLayout = (e) => setPlotW(e.nativeEvent.layout.width);
|
|
701
|
+
const plotHeight = Math.max(0, height - HERO_LABEL_HEADROOM);
|
|
702
|
+
const barHeight = (velocity) => scaleDenom > 0 ? Math.max(HERO_MIN_BAR_HEIGHT, Math.min(1, velocity / scaleDenom) * plotHeight) : HERO_MIN_BAR_HEIGHT;
|
|
703
|
+
const pendingCount = Math.max(0, (targetReps ?? 0) - doneVelocities.length);
|
|
704
|
+
const referencePx = referenceVelocity > 0 && scaleDenom > 0 ? Math.min(plotHeight, referenceVelocity / scaleDenom * plotHeight) : 0;
|
|
705
|
+
const totalSlots = doneVelocities.length + pendingCount;
|
|
706
|
+
const barWidth = plotW > 0 && totalSlots > 0 ? Math.min(HERO_BAR_MAX_WIDTH, (plotW - HERO_BAR_GAP * (totalSlots - 1)) / totalSlots) : HERO_BAR_MAX_WIDTH;
|
|
707
|
+
const labelsCrowded = plotW > 0 && barWidth < HERO_LABEL_MIN_BAR_WIDTH;
|
|
708
|
+
const heroGap = plotW === 0 ? HERO_BAR_GAP : barWidth < 16 ? 2 : barWidth < 28 ? 4 : HERO_BAR_GAP;
|
|
709
|
+
const peakIndex = doneVelocities.reduce(
|
|
710
|
+
(best, v, i) => v > doneVelocities[best] ? i : best,
|
|
711
|
+
0
|
|
712
|
+
);
|
|
713
|
+
const showBarLabel = (i) => !labelsCrowded || i === peakIndex || i === liveRepIndex;
|
|
714
|
+
const repCount = doneVelocities.length;
|
|
715
|
+
const total = Math.max(repCount, targetReps ?? repCount);
|
|
716
|
+
const label = referenceVelocity > 0 ? `Velocity chart, ${repCount} of ${total} reps, best ${formatVelocity(referenceVelocity)} meters per second` : `Velocity chart, ${repCount} of ${total} reps`;
|
|
717
|
+
const { style: externalStyle, ...restProps } = viewProps;
|
|
718
|
+
return /* @__PURE__ */ jsx(
|
|
719
|
+
View,
|
|
720
|
+
{
|
|
721
|
+
className,
|
|
722
|
+
style: [{ height }, externalStyle],
|
|
723
|
+
accessibilityRole: "image",
|
|
724
|
+
accessibilityLabel: label,
|
|
725
|
+
testID: "velocity-strip-hero",
|
|
726
|
+
...restProps,
|
|
727
|
+
children: /* @__PURE__ */ jsxs(
|
|
728
|
+
View,
|
|
729
|
+
{
|
|
730
|
+
onLayout: onPlotLayout,
|
|
731
|
+
style: {
|
|
732
|
+
flex: 1,
|
|
733
|
+
flexDirection: "row",
|
|
734
|
+
alignItems: "flex-end",
|
|
735
|
+
gap: heroGap,
|
|
736
|
+
position: "relative",
|
|
737
|
+
borderBottomWidth: 2,
|
|
738
|
+
borderBottomColor: HERO_PENDING_COLOR
|
|
739
|
+
},
|
|
740
|
+
children: [
|
|
741
|
+
referencePx > 0 && /* @__PURE__ */ jsx(
|
|
742
|
+
View,
|
|
743
|
+
{
|
|
744
|
+
accessibilityElementsHidden: true,
|
|
745
|
+
style: {
|
|
746
|
+
position: "absolute",
|
|
747
|
+
left: 0,
|
|
748
|
+
right: 0,
|
|
749
|
+
bottom: referencePx,
|
|
750
|
+
borderTopWidth: 1,
|
|
751
|
+
borderStyle: "dashed",
|
|
752
|
+
borderColor: HERO_REFERENCE_COLOR,
|
|
753
|
+
pointerEvents: "none"
|
|
754
|
+
},
|
|
755
|
+
testID: "velocity-hero-reference"
|
|
756
|
+
}
|
|
757
|
+
),
|
|
758
|
+
doneVelocities.map((velocity, i) => {
|
|
759
|
+
const isLive = liveRepIndex === i;
|
|
760
|
+
return /* @__PURE__ */ jsxs(
|
|
761
|
+
View,
|
|
762
|
+
{
|
|
763
|
+
accessibilityElementsHidden: true,
|
|
764
|
+
style: {
|
|
765
|
+
flex: 1,
|
|
766
|
+
maxWidth: HERO_BAR_MAX_WIDTH,
|
|
767
|
+
height: "100%",
|
|
768
|
+
alignItems: "center",
|
|
769
|
+
justifyContent: "flex-end"
|
|
770
|
+
},
|
|
771
|
+
children: [
|
|
772
|
+
showBarLabel(i) && /* @__PURE__ */ jsx(
|
|
773
|
+
Text,
|
|
774
|
+
{
|
|
775
|
+
className: "text-text-primary",
|
|
776
|
+
style: { fontSize: 12, fontWeight: "800", marginBottom: 4 },
|
|
777
|
+
testID: `velocity-label-${i}`,
|
|
778
|
+
children: formatVelocity(velocity)
|
|
779
|
+
}
|
|
780
|
+
),
|
|
781
|
+
/* @__PURE__ */ jsx(
|
|
782
|
+
Animated.View,
|
|
783
|
+
{
|
|
784
|
+
style: [
|
|
785
|
+
{
|
|
786
|
+
width: "100%",
|
|
787
|
+
height: barHeight(velocity),
|
|
788
|
+
borderTopLeftRadius: HERO_BAR_RADIUS,
|
|
789
|
+
borderTopRightRadius: HERO_BAR_RADIUS,
|
|
790
|
+
backgroundColor: barColorFor(velocity)
|
|
791
|
+
},
|
|
792
|
+
isLive ? { transform: [{ scale: liveScale }] } : null
|
|
793
|
+
],
|
|
794
|
+
testID: `velocity-bar-${i}`
|
|
795
|
+
}
|
|
796
|
+
)
|
|
797
|
+
]
|
|
798
|
+
},
|
|
799
|
+
i
|
|
800
|
+
);
|
|
801
|
+
}),
|
|
802
|
+
Array.from({ length: pendingCount }, (_, i) => /* @__PURE__ */ jsx(
|
|
803
|
+
View,
|
|
804
|
+
{
|
|
805
|
+
accessibilityElementsHidden: true,
|
|
806
|
+
style: {
|
|
807
|
+
flex: 1,
|
|
808
|
+
maxWidth: HERO_BAR_MAX_WIDTH,
|
|
809
|
+
height: "100%",
|
|
810
|
+
alignItems: "center",
|
|
811
|
+
justifyContent: "flex-end"
|
|
812
|
+
},
|
|
813
|
+
children: /* @__PURE__ */ jsx(
|
|
814
|
+
View,
|
|
815
|
+
{
|
|
816
|
+
style: {
|
|
817
|
+
width: "100%",
|
|
818
|
+
height: HERO_MIN_BAR_HEIGHT * 3,
|
|
819
|
+
borderWidth: 1,
|
|
820
|
+
borderStyle: "dashed",
|
|
821
|
+
borderColor: HERO_PENDING_COLOR,
|
|
822
|
+
borderTopLeftRadius: HERO_BAR_RADIUS,
|
|
823
|
+
borderTopRightRadius: HERO_BAR_RADIUS
|
|
824
|
+
},
|
|
825
|
+
testID: "velocity-slot-todo"
|
|
826
|
+
}
|
|
827
|
+
)
|
|
828
|
+
},
|
|
829
|
+
`pending-${i}`
|
|
830
|
+
))
|
|
831
|
+
]
|
|
832
|
+
}
|
|
833
|
+
)
|
|
834
|
+
}
|
|
835
|
+
);
|
|
836
|
+
}
|
|
634
837
|
function VelocityStrip({
|
|
635
838
|
velocities,
|
|
636
839
|
set,
|
|
@@ -641,6 +844,7 @@ function VelocityStrip({
|
|
|
641
844
|
onRepPress,
|
|
642
845
|
variant = "expanded",
|
|
643
846
|
height = EXPANDED_HEIGHT,
|
|
847
|
+
targetReps,
|
|
644
848
|
scale = "peak",
|
|
645
849
|
showNumbers = true,
|
|
646
850
|
showInfo = true,
|
|
@@ -666,45 +870,17 @@ function VelocityStrip({
|
|
|
666
870
|
return SET_STRIP_VARIABLE_COLOR;
|
|
667
871
|
};
|
|
668
872
|
const meanZone = hasZones ? classifyBand(meanVelocity, zones)?.label ?? "" : getVelocityZoneName(meanVelocity);
|
|
669
|
-
const prefersReducedMotion = usePrefersReducedMotion();
|
|
670
873
|
const [heightAnim] = useState(() => new Animated.Value(expanded ? height : 3));
|
|
671
874
|
const [labelOpacity] = useState(() => new Animated.Value(expanded ? 1 : 0));
|
|
672
875
|
const [infoOpacity] = useState(() => new Animated.Value(expanded ? 1 : 0));
|
|
673
|
-
const [liveScale] = useState(() => new Animated.Value(1));
|
|
674
876
|
const liveVelocity = liveRepIndex != null ? doneVelocities[liveRepIndex] : void 0;
|
|
675
877
|
const isNewPeak = liveVelocity != null && maxVelocity > 0 && liveVelocity === maxVelocity;
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if (isNewPeak) {
|
|
683
|
-
liveScale.setValue(1);
|
|
684
|
-
Animated.sequence([
|
|
685
|
-
Animated.timing(liveScale, {
|
|
686
|
-
toValue: 1.25,
|
|
687
|
-
duration: 150,
|
|
688
|
-
easing: Easing.out(Easing.quad),
|
|
689
|
-
useNativeDriver: true
|
|
690
|
-
}),
|
|
691
|
-
Animated.spring(liveScale, {
|
|
692
|
-
toValue: 1,
|
|
693
|
-
friction: 3,
|
|
694
|
-
tension: 140,
|
|
695
|
-
useNativeDriver: true
|
|
696
|
-
})
|
|
697
|
-
]).start();
|
|
698
|
-
} else {
|
|
699
|
-
liveScale.setValue(0.8);
|
|
700
|
-
Animated.timing(liveScale, {
|
|
701
|
-
toValue: 1,
|
|
702
|
-
duration: 300,
|
|
703
|
-
easing: POP_EASING,
|
|
704
|
-
useNativeDriver: true
|
|
705
|
-
}).start();
|
|
706
|
-
}
|
|
707
|
-
}, [variant, framed, liveRepIndex, liveVelocity, isNewPeak, prefersReducedMotion, liveScale]);
|
|
878
|
+
const liveScale = useLiveRepPop(
|
|
879
|
+
variant === "expanded" && framed,
|
|
880
|
+
liveRepIndex,
|
|
881
|
+
liveVelocity,
|
|
882
|
+
isNewPeak
|
|
883
|
+
);
|
|
708
884
|
useEffect(() => {
|
|
709
885
|
if (variant !== "expanded" || !framed) return;
|
|
710
886
|
Animated.parallel([
|
|
@@ -731,6 +907,24 @@ function VelocityStrip({
|
|
|
731
907
|
if (set == null && velocities == null) return null;
|
|
732
908
|
const repCount = doneVelocities.length;
|
|
733
909
|
const miniLabel = set ? setAccessibilityLabel(set, repCount) : `Velocity strip, ${repCount} reps`;
|
|
910
|
+
if (variant === "hero") {
|
|
911
|
+
const heroHeight = height === EXPANDED_HEIGHT ? HERO_HEIGHT : height;
|
|
912
|
+
return /* @__PURE__ */ jsx(
|
|
913
|
+
HeroVelocityChart,
|
|
914
|
+
{
|
|
915
|
+
doneVelocities,
|
|
916
|
+
barColorFor,
|
|
917
|
+
scaleDenom,
|
|
918
|
+
referenceVelocity: maxVelocity,
|
|
919
|
+
liveRepIndex,
|
|
920
|
+
isNewPeak,
|
|
921
|
+
targetReps,
|
|
922
|
+
height: heroHeight,
|
|
923
|
+
className,
|
|
924
|
+
viewProps: props
|
|
925
|
+
}
|
|
926
|
+
);
|
|
927
|
+
}
|
|
734
928
|
if (variant === "mini") {
|
|
735
929
|
const { style: externalStyle, ...restProps } = props;
|
|
736
930
|
return /* @__PURE__ */ jsx(
|
|
@@ -1774,6 +1968,7 @@ function SetsRepsLoad({
|
|
|
1774
1968
|
reps,
|
|
1775
1969
|
load,
|
|
1776
1970
|
unit = "lb",
|
|
1971
|
+
fontSize,
|
|
1777
1972
|
className,
|
|
1778
1973
|
...props
|
|
1779
1974
|
}) {
|
|
@@ -1788,12 +1983,12 @@ function SetsRepsLoad({
|
|
|
1788
1983
|
testID: "sets-reps-load",
|
|
1789
1984
|
...props,
|
|
1790
1985
|
children: [
|
|
1791
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, children: sets }),
|
|
1792
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${TIMES} ` }),
|
|
1793
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, children: reps }),
|
|
1794
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${AT} ` }),
|
|
1795
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, children: load }),
|
|
1796
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${unit}` })
|
|
1986
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: sets }),
|
|
1987
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${TIMES} ` }),
|
|
1988
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: reps }),
|
|
1989
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${AT} ` }),
|
|
1990
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: load }),
|
|
1991
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${unit}` })
|
|
1797
1992
|
]
|
|
1798
1993
|
}
|
|
1799
1994
|
);
|
|
@@ -2107,36 +2302,34 @@ function alpha(color, opacity) {
|
|
|
2107
2302
|
}
|
|
2108
2303
|
return color;
|
|
2109
2304
|
}
|
|
2305
|
+
|
|
2306
|
+
// src/components/custom/Workout/TempoDisplay.tsx
|
|
2110
2307
|
var t2 = getSemanticColors("dark");
|
|
2111
|
-
var
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
const ratio = elapsedMs / targetMs;
|
|
2118
|
-
if (ratio > 1 + TEMPO_PACING.behindThresholdPct) return "behind";
|
|
2119
|
-
return "on-pace";
|
|
2120
|
-
}
|
|
2308
|
+
var INTER = "Inter, sans-serif";
|
|
2309
|
+
var TEXT_TERTIARY = "#6B7280";
|
|
2310
|
+
var STATUS_ERROR = t2["status-error"];
|
|
2311
|
+
var STATUS_SUCCESS = t2["status-success"];
|
|
2312
|
+
var STATUS_WARNING = t2["status-warning"];
|
|
2313
|
+
var ON_TARGET_MS = 100;
|
|
2121
2314
|
function getTempoFillPct(elapsedMs, targetMs) {
|
|
2122
2315
|
if (!targetMs) return 100;
|
|
2123
2316
|
return Math.min(100, elapsedMs / targetMs * 100);
|
|
2124
2317
|
}
|
|
2125
|
-
({
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2318
|
+
function activeNumberTone(elapsedMs, targetMs) {
|
|
2319
|
+
if (targetMs == null) return t2["text-primary"];
|
|
2320
|
+
const remainingMs = targetMs - elapsedMs;
|
|
2321
|
+
if (remainingMs > ON_TARGET_MS) return STATUS_WARNING;
|
|
2322
|
+
if (remainingMs >= -ON_TARGET_MS) return STATUS_SUCCESS;
|
|
2323
|
+
return STATUS_ERROR;
|
|
2324
|
+
}
|
|
2325
|
+
function liveReadoutText(elapsedMs, targetMs, readout) {
|
|
2326
|
+
const seconds = readout === "countup" ? elapsedMs / 1e3 : (targetMs - elapsedMs) / 1e3;
|
|
2327
|
+
return seconds.toFixed(1);
|
|
2328
|
+
}
|
|
2136
2329
|
var phaseColors = {
|
|
2137
|
-
eccentric:
|
|
2330
|
+
eccentric: primitiveRamps.magenta[400],
|
|
2138
2331
|
pauseBottom: TEXT_TERTIARY,
|
|
2139
|
-
concentric:
|
|
2332
|
+
concentric: primitiveRamps.cyan[300],
|
|
2140
2333
|
pauseTop: TEXT_TERTIARY,
|
|
2141
2334
|
dash: TEXT_TERTIARY
|
|
2142
2335
|
};
|
|
@@ -2156,63 +2349,98 @@ var LIVE_PHASES = [
|
|
|
2156
2349
|
{ key: "concentric", color: phaseColors.concentric },
|
|
2157
2350
|
{ key: "pauseTop", color: phaseColors.pauseTop }
|
|
2158
2351
|
];
|
|
2352
|
+
function CellFill({ color, pct }) {
|
|
2353
|
+
return /* @__PURE__ */ jsx(
|
|
2354
|
+
View,
|
|
2355
|
+
{
|
|
2356
|
+
style: {
|
|
2357
|
+
position: "absolute",
|
|
2358
|
+
left: 2,
|
|
2359
|
+
right: 2,
|
|
2360
|
+
bottom: 0,
|
|
2361
|
+
height: `${pct}%`,
|
|
2362
|
+
backgroundColor: alpha(color, 0.28),
|
|
2363
|
+
borderRadius: 3
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2368
|
+
var MONO = "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
|
|
2369
|
+
var READOUT_MAX_CHARS = 5;
|
|
2159
2370
|
function LiveTempoCell({
|
|
2160
2371
|
value,
|
|
2161
2372
|
color,
|
|
2162
|
-
|
|
2373
|
+
status,
|
|
2163
2374
|
phaseElapsedMs,
|
|
2164
|
-
|
|
2375
|
+
completedMs,
|
|
2376
|
+
fontSize,
|
|
2377
|
+
readout
|
|
2165
2378
|
}) {
|
|
2166
|
-
if (!isActive) {
|
|
2167
|
-
return /* @__PURE__ */ jsx(TempoValue, { value, color: alpha(color, 0.35), fontSize });
|
|
2168
|
-
}
|
|
2169
2379
|
const targetMs = value > 0 ? value * 1e3 : null;
|
|
2170
|
-
const
|
|
2380
|
+
const cellW = Math.ceil(fontSize * 0.62 * READOUT_MAX_CHARS);
|
|
2381
|
+
const wrap = {
|
|
2382
|
+
position: "relative",
|
|
2383
|
+
width: cellW,
|
|
2384
|
+
minHeight: Math.round(fontSize * 1.25),
|
|
2385
|
+
alignItems: "center",
|
|
2386
|
+
justifyContent: "center"
|
|
2387
|
+
};
|
|
2388
|
+
const num = (c, text) => /* @__PURE__ */ jsx(Text, { style: { fontFamily: MONO, fontSize, color: c, fontWeight: "700" }, children: text });
|
|
2389
|
+
if (status === "upcoming") {
|
|
2390
|
+
const targetText = targetMs != null ? (targetMs / 1e3).toFixed(1) : String(value);
|
|
2391
|
+
return /* @__PURE__ */ jsx(View, { style: wrap, children: num(color, targetText) });
|
|
2392
|
+
}
|
|
2393
|
+
if (status === "done") {
|
|
2394
|
+
const finalMs = completedMs ?? targetMs ?? 0;
|
|
2395
|
+
const finalText = targetMs != null ? liveReadoutText(finalMs, targetMs, readout) : String(value);
|
|
2396
|
+
const finalTone = targetMs != null ? activeNumberTone(finalMs, targetMs) : color;
|
|
2397
|
+
return /* @__PURE__ */ jsxs(View, { style: wrap, testID: "tempo-live-done", children: [
|
|
2398
|
+
/* @__PURE__ */ jsx(CellFill, { color, pct: 100 }),
|
|
2399
|
+
num(finalTone, finalText)
|
|
2400
|
+
] });
|
|
2401
|
+
}
|
|
2402
|
+
const numberTone = activeNumberTone(phaseElapsedMs, targetMs);
|
|
2171
2403
|
const fillPct = getTempoFillPct(phaseElapsedMs, targetMs);
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
style: {
|
|
2177
|
-
position: "absolute",
|
|
2178
|
-
left: 0,
|
|
2179
|
-
top: 0,
|
|
2180
|
-
bottom: 0,
|
|
2181
|
-
width: `${fillPct}%`,
|
|
2182
|
-
backgroundColor: alpha(barColor, 0.3),
|
|
2183
|
-
borderRadius: 2
|
|
2184
|
-
}
|
|
2185
|
-
}
|
|
2186
|
-
),
|
|
2187
|
-
/* @__PURE__ */ jsx(TempoValue, { value, color: barColor, fontSize })
|
|
2404
|
+
const activeText = targetMs != null ? liveReadoutText(phaseElapsedMs, targetMs, readout) : String(value);
|
|
2405
|
+
return /* @__PURE__ */ jsxs(View, { style: wrap, testID: "tempo-live-active", children: [
|
|
2406
|
+
/* @__PURE__ */ jsx(CellFill, { color, pct: fillPct }),
|
|
2407
|
+
num(numberTone, activeText)
|
|
2188
2408
|
] });
|
|
2189
2409
|
}
|
|
2190
2410
|
function LiveTempoRow({
|
|
2191
2411
|
values,
|
|
2192
2412
|
live,
|
|
2193
|
-
fontSize
|
|
2413
|
+
fontSize,
|
|
2414
|
+
readout
|
|
2194
2415
|
}) {
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
{
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2416
|
+
const activeIndex = live.activePhase ? LIVE_PHASES.findIndex((p) => p.key === live.activePhase) : -1;
|
|
2417
|
+
return /* @__PURE__ */ jsx(Fragment, { children: LIVE_PHASES.map((phase, i) => {
|
|
2418
|
+
const status = activeIndex < 0 || i > activeIndex ? "upcoming" : i < activeIndex ? "done" : "active";
|
|
2419
|
+
return /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
2420
|
+
i > 0 && /* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2421
|
+
/* @__PURE__ */ jsx(
|
|
2422
|
+
LiveTempoCell,
|
|
2423
|
+
{
|
|
2424
|
+
value: values[i],
|
|
2425
|
+
color: phase.color,
|
|
2426
|
+
status,
|
|
2427
|
+
phaseElapsedMs: live.phaseElapsedMs,
|
|
2428
|
+
completedMs: live.completed?.[phase.key],
|
|
2429
|
+
fontSize,
|
|
2430
|
+
readout
|
|
2431
|
+
}
|
|
2432
|
+
)
|
|
2433
|
+
] }, phase.key);
|
|
2434
|
+
}) });
|
|
2208
2435
|
}
|
|
2209
2436
|
function TempoDisplay({
|
|
2210
2437
|
tempo,
|
|
2211
2438
|
size = "md",
|
|
2212
|
-
|
|
2439
|
+
fontSize: fontSizeProp,
|
|
2213
2440
|
showLabel = true,
|
|
2214
2441
|
showInfo = true,
|
|
2215
2442
|
live,
|
|
2443
|
+
liveReadout = "countdown",
|
|
2216
2444
|
onPress,
|
|
2217
2445
|
className,
|
|
2218
2446
|
...props
|
|
@@ -2220,8 +2448,11 @@ function TempoDisplay({
|
|
|
2220
2448
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
2221
2449
|
const [eccentric, pauseBottom, concentric, pauseTop] = roundTempo(tempo);
|
|
2222
2450
|
const isSm = size === "sm";
|
|
2223
|
-
const fontSize = isSm ? 9 : 11;
|
|
2224
|
-
const
|
|
2451
|
+
const fontSize = fontSizeProp ?? (isSm ? 9 : 11);
|
|
2452
|
+
const chromePadX = Math.round(fontSize * 0.6);
|
|
2453
|
+
const chromePadY = Math.round(fontSize * 0.3);
|
|
2454
|
+
const chromeRadius = Math.round(fontSize * 0.4);
|
|
2455
|
+
const labelFont = Math.max(9, Math.round(fontSize * 0.5));
|
|
2225
2456
|
const handlePress = useCallback(() => {
|
|
2226
2457
|
if (onPress) {
|
|
2227
2458
|
onPress();
|
|
@@ -2238,9 +2469,9 @@ function TempoDisplay({
|
|
|
2238
2469
|
flexDirection: "row",
|
|
2239
2470
|
alignItems: "center",
|
|
2240
2471
|
backgroundColor: "#1C1C1C",
|
|
2241
|
-
paddingHorizontal:
|
|
2242
|
-
paddingVertical:
|
|
2243
|
-
borderRadius:
|
|
2472
|
+
paddingHorizontal: chromePadX,
|
|
2473
|
+
paddingVertical: chromePadY,
|
|
2474
|
+
borderRadius: chromeRadius
|
|
2244
2475
|
},
|
|
2245
2476
|
...props,
|
|
2246
2477
|
children: [
|
|
@@ -2249,12 +2480,13 @@ function TempoDisplay({
|
|
|
2249
2480
|
{
|
|
2250
2481
|
style: {
|
|
2251
2482
|
fontFamily: INTER,
|
|
2252
|
-
fontSize:
|
|
2483
|
+
fontSize: labelFont,
|
|
2253
2484
|
fontWeight: "500",
|
|
2254
|
-
|
|
2485
|
+
// Live-muted green while a rep is running, tertiary at rest.
|
|
2486
|
+
color: live ? t2["status-live-muted"] : TEXT_TERTIARY,
|
|
2255
2487
|
letterSpacing: 0.5,
|
|
2256
2488
|
textTransform: "uppercase",
|
|
2257
|
-
marginRight:
|
|
2489
|
+
marginRight: Math.round(fontSize * 0.5)
|
|
2258
2490
|
},
|
|
2259
2491
|
children: "TEMPO"
|
|
2260
2492
|
}
|
|
@@ -2264,36 +2496,20 @@ function TempoDisplay({
|
|
|
2264
2496
|
{
|
|
2265
2497
|
values: [eccentric, pauseBottom, concentric, pauseTop],
|
|
2266
2498
|
live,
|
|
2267
|
-
fontSize
|
|
2268
|
-
|
|
2269
|
-
) : colored ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2270
|
-
/* @__PURE__ */ jsx(TempoValue, { value: eccentric, color: phaseColors.eccentric, fontSize }),
|
|
2271
|
-
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2272
|
-
/* @__PURE__ */ jsx(TempoValue, { value: pauseBottom, color: phaseColors.pauseBottom, fontSize }),
|
|
2273
|
-
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2274
|
-
/* @__PURE__ */ jsx(TempoValue, { value: concentric, color: phaseColors.concentric, fontSize }),
|
|
2275
|
-
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2276
|
-
/* @__PURE__ */ jsx(TempoValue, { value: pauseTop, color: phaseColors.pauseTop, fontSize })
|
|
2277
|
-
] }) : /* @__PURE__ */ jsxs(
|
|
2278
|
-
Text,
|
|
2279
|
-
{
|
|
2280
|
-
style: {
|
|
2281
|
-
fontFamily: INTER,
|
|
2282
|
-
fontSize,
|
|
2283
|
-
color: monoColor,
|
|
2284
|
-
fontWeight: "600",
|
|
2285
|
-
letterSpacing: 1
|
|
2286
|
-
},
|
|
2287
|
-
children: [
|
|
2288
|
-
eccentric,
|
|
2289
|
-
"-",
|
|
2290
|
-
pauseBottom,
|
|
2291
|
-
"-",
|
|
2292
|
-
concentric,
|
|
2293
|
-
"-",
|
|
2294
|
-
pauseTop
|
|
2295
|
-
]
|
|
2499
|
+
fontSize,
|
|
2500
|
+
readout: liveReadout
|
|
2296
2501
|
}
|
|
2502
|
+
) : (
|
|
2503
|
+
// Static prescription: the phase-coloured lockup (the same colours the live row rests at).
|
|
2504
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2505
|
+
/* @__PURE__ */ jsx(TempoValue, { value: eccentric, color: phaseColors.eccentric, fontSize }),
|
|
2506
|
+
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2507
|
+
/* @__PURE__ */ jsx(TempoValue, { value: pauseBottom, color: phaseColors.pauseBottom, fontSize }),
|
|
2508
|
+
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2509
|
+
/* @__PURE__ */ jsx(TempoValue, { value: concentric, color: phaseColors.concentric, fontSize }),
|
|
2510
|
+
/* @__PURE__ */ jsx(TempoSeparator, { color: phaseColors.dash, fontSize }),
|
|
2511
|
+
/* @__PURE__ */ jsx(TempoValue, { value: pauseTop, color: phaseColors.pauseTop, fontSize })
|
|
2512
|
+
] })
|
|
2297
2513
|
) })
|
|
2298
2514
|
]
|
|
2299
2515
|
}
|
|
@@ -2378,14 +2594,14 @@ function TempoDisplay({
|
|
|
2378
2594
|
}
|
|
2379
2595
|
);
|
|
2380
2596
|
}
|
|
2381
|
-
var
|
|
2597
|
+
var t3 = getSemanticColors("dark");
|
|
2382
2598
|
var INDICATOR_CONFIG = {
|
|
2383
|
-
imbalance: { Icon: ScaleIcon, color:
|
|
2384
|
-
overshoot: { Icon: AlertTriangleIcon, color:
|
|
2385
|
-
"velocity-loss": { Icon: TrendingDownIcon, color:
|
|
2386
|
-
"missed-reps": { Icon: CircleSlashIcon, color:
|
|
2387
|
-
pr: { Icon: AwardIcon, color:
|
|
2388
|
-
info: { Icon: InfoIcon, color:
|
|
2599
|
+
imbalance: { Icon: ScaleIcon, color: t3["status-error"], label: "Left/right imbalance" },
|
|
2600
|
+
overshoot: { Icon: AlertTriangleIcon, color: t3["status-error"], label: "Load overshoot" },
|
|
2601
|
+
"velocity-loss": { Icon: TrendingDownIcon, color: t3["status-warning"], label: "Velocity loss" },
|
|
2602
|
+
"missed-reps": { Icon: CircleSlashIcon, color: t3["status-warning"], label: "Missed reps" },
|
|
2603
|
+
pr: { Icon: AwardIcon, color: t3["status-success"], label: "Personal record" },
|
|
2604
|
+
info: { Icon: InfoIcon, color: t3["status-info"], label: "More info" }
|
|
2389
2605
|
};
|
|
2390
2606
|
function ExerciseIndicator({ kind, onPress, className, ...props }) {
|
|
2391
2607
|
const { Icon, color, label } = INDICATOR_CONFIG[kind];
|
|
@@ -2991,9 +3207,270 @@ function useTimer(options = {}) {
|
|
|
2991
3207
|
const done = durationMs != null && elapsedMs >= durationMs;
|
|
2992
3208
|
return { elapsedMs, remainingMs, progress, label, done };
|
|
2993
3209
|
}
|
|
3210
|
+
var colorVarMap = {
|
|
3211
|
+
primary: "var(--color-brand-primary)",
|
|
3212
|
+
secondary: "var(--color-brand-secondary)",
|
|
3213
|
+
success: "var(--color-status-success)",
|
|
3214
|
+
error: "var(--color-status-error)",
|
|
3215
|
+
warning: "var(--color-status-warning)",
|
|
3216
|
+
info: "var(--color-status-info)"
|
|
3217
|
+
};
|
|
3218
|
+
function CircularProgress({
|
|
3219
|
+
value = 0,
|
|
3220
|
+
max = 100,
|
|
3221
|
+
isIndeterminate = false,
|
|
3222
|
+
size = 48,
|
|
3223
|
+
strokeWidth = 4,
|
|
3224
|
+
color = "primary",
|
|
3225
|
+
showValue = false,
|
|
3226
|
+
formatValue: formatValue2 = (v, m) => `${Math.round(v / m * 100)}%`,
|
|
3227
|
+
children,
|
|
3228
|
+
fill = false,
|
|
3229
|
+
className,
|
|
3230
|
+
...props
|
|
3231
|
+
}) {
|
|
3232
|
+
const percentage = Math.min(Math.max(value / max * 100, 0), 100);
|
|
3233
|
+
const radius = (size - strokeWidth) / 2;
|
|
3234
|
+
const circumference = 2 * Math.PI * radius;
|
|
3235
|
+
const strokeDashoffset = circumference - percentage / 100 * circumference;
|
|
3236
|
+
const center = size / 2;
|
|
3237
|
+
const boxStyle = fill ? { width: "100%", aspectRatio: 1 } : { width: size, height: size };
|
|
3238
|
+
return /* @__PURE__ */ jsxs(
|
|
3239
|
+
View,
|
|
3240
|
+
{
|
|
3241
|
+
className: cn("items-center justify-center", className),
|
|
3242
|
+
style: boxStyle,
|
|
3243
|
+
accessibilityRole: "progressbar",
|
|
3244
|
+
accessibilityValue: {
|
|
3245
|
+
min: 0,
|
|
3246
|
+
max,
|
|
3247
|
+
now: isIndeterminate ? void 0 : value
|
|
3248
|
+
},
|
|
3249
|
+
...props,
|
|
3250
|
+
children: [
|
|
3251
|
+
/* @__PURE__ */ jsx(View, { className: cn(isIndeterminate && "animate-spin"), style: boxStyle, children: /* @__PURE__ */ jsxs(
|
|
3252
|
+
"svg",
|
|
3253
|
+
{
|
|
3254
|
+
width: "100%",
|
|
3255
|
+
height: "100%",
|
|
3256
|
+
viewBox: `0 0 ${size} ${size}`,
|
|
3257
|
+
style: { position: "absolute" },
|
|
3258
|
+
children: [
|
|
3259
|
+
/* @__PURE__ */ jsx(
|
|
3260
|
+
"circle",
|
|
3261
|
+
{
|
|
3262
|
+
cx: center,
|
|
3263
|
+
cy: center,
|
|
3264
|
+
r: radius,
|
|
3265
|
+
fill: "none",
|
|
3266
|
+
stroke: "var(--color-border-default)",
|
|
3267
|
+
strokeWidth
|
|
3268
|
+
}
|
|
3269
|
+
),
|
|
3270
|
+
/* @__PURE__ */ jsx(
|
|
3271
|
+
"circle",
|
|
3272
|
+
{
|
|
3273
|
+
cx: center,
|
|
3274
|
+
cy: center,
|
|
3275
|
+
r: radius,
|
|
3276
|
+
fill: "none",
|
|
3277
|
+
stroke: colorVarMap[color],
|
|
3278
|
+
strokeWidth,
|
|
3279
|
+
strokeLinecap: "round",
|
|
3280
|
+
strokeDasharray: circumference,
|
|
3281
|
+
strokeDashoffset: isIndeterminate ? circumference * 0.75 : strokeDashoffset,
|
|
3282
|
+
transform: `rotate(-90 ${center} ${center})`,
|
|
3283
|
+
style: { transition: "stroke-dashoffset 300ms cubic-bezier(0.22, 1, 0.36, 1)" }
|
|
3284
|
+
}
|
|
3285
|
+
)
|
|
3286
|
+
]
|
|
3287
|
+
}
|
|
3288
|
+
) }),
|
|
3289
|
+
children != null ? /* @__PURE__ */ jsx(
|
|
3290
|
+
View,
|
|
3291
|
+
{
|
|
3292
|
+
style: {
|
|
3293
|
+
position: "absolute",
|
|
3294
|
+
alignItems: "center",
|
|
3295
|
+
justifyContent: "center",
|
|
3296
|
+
pointerEvents: "none"
|
|
3297
|
+
},
|
|
3298
|
+
children
|
|
3299
|
+
}
|
|
3300
|
+
) : showValue && !isIndeterminate && /* @__PURE__ */ jsx(
|
|
3301
|
+
Text,
|
|
3302
|
+
{
|
|
3303
|
+
className: "text-xs font-semibold text-text-primary absolute",
|
|
3304
|
+
style: { fontSize: Math.max(size * 0.22, 10) },
|
|
3305
|
+
children: formatValue2(value, max)
|
|
3306
|
+
}
|
|
3307
|
+
)
|
|
3308
|
+
]
|
|
3309
|
+
}
|
|
3310
|
+
);
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
// src/components/custom/CircularTimer/CircularTimer.tsx
|
|
3314
|
+
function CircularTimer({
|
|
3315
|
+
durationMs,
|
|
3316
|
+
elapsedMs,
|
|
3317
|
+
mode = "down",
|
|
3318
|
+
size = 160,
|
|
3319
|
+
strokeWidth = 8,
|
|
3320
|
+
fill = false,
|
|
3321
|
+
color = "primary",
|
|
3322
|
+
doneLabel,
|
|
3323
|
+
doneColor = "success",
|
|
3324
|
+
controls,
|
|
3325
|
+
accessibilityLabel: accessibilityLabel2,
|
|
3326
|
+
testID
|
|
3327
|
+
}) {
|
|
3328
|
+
const { remainingMs, progress, label, done } = useTimer({ mode, durationMs, elapsedMs });
|
|
3329
|
+
const isDone = done && mode === "down";
|
|
3330
|
+
const showDone = isDone && doneLabel != null;
|
|
3331
|
+
const remainingFrac = durationMs > 0 ? Math.max(0, Math.min(1, remainingMs / durationMs)) : 0;
|
|
3332
|
+
const arc = mode === "down" ? showDone ? 1 : remainingFrac : progress;
|
|
3333
|
+
const ringColor = showDone ? doneColor : color;
|
|
3334
|
+
const remainingSec = Math.ceil(Math.max(0, remainingMs) / 1e3);
|
|
3335
|
+
const a11y = accessibilityLabel2 ?? (isDone ? "Timer complete" : `${remainingSec} seconds remaining`);
|
|
3336
|
+
return /* @__PURE__ */ jsxs(
|
|
3337
|
+
View,
|
|
3338
|
+
{
|
|
3339
|
+
style: { alignItems: "center", gap: 16 },
|
|
3340
|
+
accessibilityRole: "timer",
|
|
3341
|
+
accessibilityLabel: a11y,
|
|
3342
|
+
testID: testID ?? "circular-timer",
|
|
3343
|
+
children: [
|
|
3344
|
+
/* @__PURE__ */ jsx(
|
|
3345
|
+
CircularProgress,
|
|
3346
|
+
{
|
|
3347
|
+
value: arc,
|
|
3348
|
+
max: 1,
|
|
3349
|
+
size,
|
|
3350
|
+
strokeWidth,
|
|
3351
|
+
fill,
|
|
3352
|
+
color: ringColor,
|
|
3353
|
+
accessibilityLabel: "Timer ring",
|
|
3354
|
+
testID: "circular-timer-ring",
|
|
3355
|
+
children: /* @__PURE__ */ jsx(
|
|
3356
|
+
Text,
|
|
3357
|
+
{
|
|
3358
|
+
className: showDone ? void 0 : "text-text-primary",
|
|
3359
|
+
style: {
|
|
3360
|
+
fontSize: Math.round(size * (showDone ? 0.28 : 0.24)),
|
|
3361
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
3362
|
+
fontWeight: "800",
|
|
3363
|
+
fontVariant: ["tabular-nums"],
|
|
3364
|
+
letterSpacing: showDone ? 1 : -1,
|
|
3365
|
+
...showDone ? { color: colorVarMap[doneColor] } : null
|
|
3366
|
+
},
|
|
3367
|
+
testID: "circular-timer-label",
|
|
3368
|
+
children: showDone ? doneLabel : label
|
|
3369
|
+
}
|
|
3370
|
+
)
|
|
3371
|
+
}
|
|
3372
|
+
),
|
|
3373
|
+
controls
|
|
3374
|
+
]
|
|
3375
|
+
}
|
|
3376
|
+
);
|
|
3377
|
+
}
|
|
2994
3378
|
|
|
2995
3379
|
// src/components/custom/Workout/RestTimer.tsx
|
|
2996
3380
|
var BRAND_PRIMARY3 = getSemanticColors("dark")["brand-primary"];
|
|
3381
|
+
var RING_DEFAULT_SIZE = 180;
|
|
3382
|
+
function RestActions({ onAddTime, onSkip }) {
|
|
3383
|
+
return /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
3384
|
+
/* @__PURE__ */ jsx(
|
|
3385
|
+
Pressable,
|
|
3386
|
+
{
|
|
3387
|
+
onPress: onAddTime,
|
|
3388
|
+
style: {
|
|
3389
|
+
backgroundColor: "rgba(255,255,255,0.06)",
|
|
3390
|
+
paddingVertical: 8,
|
|
3391
|
+
paddingHorizontal: 20,
|
|
3392
|
+
borderRadius: 8
|
|
3393
|
+
},
|
|
3394
|
+
accessibilityRole: "button",
|
|
3395
|
+
accessibilityLabel: "Add 30 seconds",
|
|
3396
|
+
testID: "rest-timer-add-time",
|
|
3397
|
+
children: /* @__PURE__ */ jsx(
|
|
3398
|
+
Text,
|
|
3399
|
+
{
|
|
3400
|
+
className: "text-text-secondary",
|
|
3401
|
+
style: { fontSize: 11, fontFamily: "Inter, sans-serif", fontWeight: "600" },
|
|
3402
|
+
children: "+30s"
|
|
3403
|
+
}
|
|
3404
|
+
)
|
|
3405
|
+
}
|
|
3406
|
+
),
|
|
3407
|
+
/* @__PURE__ */ jsx(
|
|
3408
|
+
Pressable,
|
|
3409
|
+
{
|
|
3410
|
+
onPress: onSkip,
|
|
3411
|
+
style: {
|
|
3412
|
+
backgroundColor: "rgba(255,121,0,0.12)",
|
|
3413
|
+
paddingVertical: 8,
|
|
3414
|
+
paddingHorizontal: 20,
|
|
3415
|
+
borderRadius: 8
|
|
3416
|
+
},
|
|
3417
|
+
accessibilityRole: "button",
|
|
3418
|
+
accessibilityLabel: "Skip rest",
|
|
3419
|
+
testID: "rest-timer-skip",
|
|
3420
|
+
children: /* @__PURE__ */ jsx(
|
|
3421
|
+
Text,
|
|
3422
|
+
{
|
|
3423
|
+
style: {
|
|
3424
|
+
fontSize: 11,
|
|
3425
|
+
fontFamily: "Inter, sans-serif",
|
|
3426
|
+
fontWeight: "600",
|
|
3427
|
+
color: BRAND_PRIMARY3
|
|
3428
|
+
},
|
|
3429
|
+
children: "Skip"
|
|
3430
|
+
}
|
|
3431
|
+
)
|
|
3432
|
+
}
|
|
3433
|
+
)
|
|
3434
|
+
] });
|
|
3435
|
+
}
|
|
3436
|
+
function RestTimerRing({
|
|
3437
|
+
totalSeconds,
|
|
3438
|
+
elapsedMs,
|
|
3439
|
+
remainingSec,
|
|
3440
|
+
done,
|
|
3441
|
+
size,
|
|
3442
|
+
nextSetInfo,
|
|
3443
|
+
displayOnly,
|
|
3444
|
+
onSkip,
|
|
3445
|
+
onAddTime
|
|
3446
|
+
}) {
|
|
3447
|
+
const a11yLabel = done ? "Rest complete, next set ready" : `Rest timer, ${Math.max(0, remainingSec)} seconds remaining`;
|
|
3448
|
+
return /* @__PURE__ */ jsxs(View, { style: { alignItems: "center", gap: 16 }, testID: "rest-timer", children: [
|
|
3449
|
+
/* @__PURE__ */ jsx(
|
|
3450
|
+
CircularTimer,
|
|
3451
|
+
{
|
|
3452
|
+
durationMs: totalSeconds * 1e3,
|
|
3453
|
+
elapsedMs,
|
|
3454
|
+
mode: "down",
|
|
3455
|
+
size,
|
|
3456
|
+
doneLabel: "GO",
|
|
3457
|
+
doneColor: "success",
|
|
3458
|
+
accessibilityLabel: a11yLabel,
|
|
3459
|
+
controls: !displayOnly ? /* @__PURE__ */ jsx(RestActions, { onAddTime, onSkip }) : void 0,
|
|
3460
|
+
testID: "rest-timer-ring"
|
|
3461
|
+
}
|
|
3462
|
+
),
|
|
3463
|
+
nextSetInfo != null && /* @__PURE__ */ jsx(
|
|
3464
|
+
Text,
|
|
3465
|
+
{
|
|
3466
|
+
className: "text-text-tertiary",
|
|
3467
|
+
style: { fontSize: 13, fontFamily: "Inter, sans-serif" },
|
|
3468
|
+
testID: "rest-timer-next-set",
|
|
3469
|
+
children: nextSetInfo
|
|
3470
|
+
}
|
|
3471
|
+
)
|
|
3472
|
+
] });
|
|
3473
|
+
}
|
|
2997
3474
|
function RestTimer({
|
|
2998
3475
|
totalSeconds,
|
|
2999
3476
|
elapsedMs,
|
|
@@ -3001,12 +3478,15 @@ function RestTimer({
|
|
|
3001
3478
|
onAddTime,
|
|
3002
3479
|
nextSetInfo,
|
|
3003
3480
|
visible,
|
|
3004
|
-
displayOnly = false
|
|
3481
|
+
displayOnly = false,
|
|
3482
|
+
variant = "bar",
|
|
3483
|
+
size = RING_DEFAULT_SIZE
|
|
3005
3484
|
}) {
|
|
3006
3485
|
const {
|
|
3007
3486
|
remainingMs,
|
|
3008
3487
|
progress,
|
|
3009
|
-
label: timeDisplay
|
|
3488
|
+
label: timeDisplay,
|
|
3489
|
+
done
|
|
3010
3490
|
} = useTimer({
|
|
3011
3491
|
mode: "down",
|
|
3012
3492
|
durationMs: totalSeconds * 1e3,
|
|
@@ -3015,6 +3495,22 @@ function RestTimer({
|
|
|
3015
3495
|
const remainingSec = Math.ceil(remainingMs / 1e3);
|
|
3016
3496
|
const progressPct = progress * 100;
|
|
3017
3497
|
if (!visible) return null;
|
|
3498
|
+
if (variant === "ring") {
|
|
3499
|
+
return /* @__PURE__ */ jsx(
|
|
3500
|
+
RestTimerRing,
|
|
3501
|
+
{
|
|
3502
|
+
totalSeconds,
|
|
3503
|
+
elapsedMs,
|
|
3504
|
+
remainingSec,
|
|
3505
|
+
done,
|
|
3506
|
+
size,
|
|
3507
|
+
nextSetInfo,
|
|
3508
|
+
displayOnly,
|
|
3509
|
+
onSkip,
|
|
3510
|
+
onAddTime
|
|
3511
|
+
}
|
|
3512
|
+
);
|
|
3513
|
+
}
|
|
3018
3514
|
return /* @__PURE__ */ jsxs(
|
|
3019
3515
|
View,
|
|
3020
3516
|
{
|
|
@@ -3112,62 +3608,7 @@ function RestTimer({
|
|
|
3112
3608
|
)
|
|
3113
3609
|
}
|
|
3114
3610
|
),
|
|
3115
|
-
!displayOnly && /* @__PURE__ */
|
|
3116
|
-
/* @__PURE__ */ jsx(
|
|
3117
|
-
Pressable,
|
|
3118
|
-
{
|
|
3119
|
-
onPress: onAddTime,
|
|
3120
|
-
style: {
|
|
3121
|
-
backgroundColor: "rgba(255,255,255,0.06)",
|
|
3122
|
-
paddingVertical: 8,
|
|
3123
|
-
paddingHorizontal: 20,
|
|
3124
|
-
borderRadius: 8
|
|
3125
|
-
},
|
|
3126
|
-
accessibilityRole: "button",
|
|
3127
|
-
accessibilityLabel: "Add 30 seconds",
|
|
3128
|
-
testID: "rest-timer-add-time",
|
|
3129
|
-
children: /* @__PURE__ */ jsx(
|
|
3130
|
-
Text,
|
|
3131
|
-
{
|
|
3132
|
-
className: "text-text-secondary",
|
|
3133
|
-
style: {
|
|
3134
|
-
fontSize: 11,
|
|
3135
|
-
fontFamily: "Inter, sans-serif",
|
|
3136
|
-
fontWeight: "600"
|
|
3137
|
-
},
|
|
3138
|
-
children: "+30s"
|
|
3139
|
-
}
|
|
3140
|
-
)
|
|
3141
|
-
}
|
|
3142
|
-
),
|
|
3143
|
-
/* @__PURE__ */ jsx(
|
|
3144
|
-
Pressable,
|
|
3145
|
-
{
|
|
3146
|
-
onPress: onSkip,
|
|
3147
|
-
style: {
|
|
3148
|
-
backgroundColor: "rgba(255,121,0,0.12)",
|
|
3149
|
-
paddingVertical: 8,
|
|
3150
|
-
paddingHorizontal: 20,
|
|
3151
|
-
borderRadius: 8
|
|
3152
|
-
},
|
|
3153
|
-
accessibilityRole: "button",
|
|
3154
|
-
accessibilityLabel: "Skip rest",
|
|
3155
|
-
testID: "rest-timer-skip",
|
|
3156
|
-
children: /* @__PURE__ */ jsx(
|
|
3157
|
-
Text,
|
|
3158
|
-
{
|
|
3159
|
-
style: {
|
|
3160
|
-
fontSize: 11,
|
|
3161
|
-
fontFamily: "Inter, sans-serif",
|
|
3162
|
-
fontWeight: "600",
|
|
3163
|
-
color: BRAND_PRIMARY3
|
|
3164
|
-
},
|
|
3165
|
-
children: "Skip"
|
|
3166
|
-
}
|
|
3167
|
-
)
|
|
3168
|
-
}
|
|
3169
|
-
)
|
|
3170
|
-
] })
|
|
3611
|
+
!displayOnly && /* @__PURE__ */ jsx(RestActions, { onAddTime, onSkip })
|
|
3171
3612
|
]
|
|
3172
3613
|
}
|
|
3173
3614
|
);
|
|
@@ -3957,11 +4398,11 @@ function CardContent({ children, className }) {
|
|
|
3957
4398
|
function CardFooter({ children, className }) {
|
|
3958
4399
|
return /* @__PURE__ */ jsx(View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
|
|
3959
4400
|
}
|
|
3960
|
-
var
|
|
4401
|
+
var t4 = getSemanticColors("dark");
|
|
3961
4402
|
var solidVariantColors = {
|
|
3962
|
-
success:
|
|
3963
|
-
warning:
|
|
3964
|
-
error:
|
|
4403
|
+
success: t4["status-success"],
|
|
4404
|
+
warning: t4["status-warning"],
|
|
4405
|
+
error: t4["status-error"],
|
|
3965
4406
|
neutral: "#6B7280"
|
|
3966
4407
|
};
|
|
3967
4408
|
var ringVariantStyles = {
|
|
@@ -4001,8 +4442,8 @@ var iconColors = {
|
|
|
4001
4442
|
warning: "#6B4000",
|
|
4002
4443
|
error: "#5C1A1A",
|
|
4003
4444
|
neutral: "#D1D5DB",
|
|
4004
|
-
"on-track":
|
|
4005
|
-
deviation:
|
|
4445
|
+
"on-track": t4["status-success"],
|
|
4446
|
+
deviation: t4["status-warning"],
|
|
4006
4447
|
future: "#6B7280"
|
|
4007
4448
|
};
|
|
4008
4449
|
var sizeDimensions = {
|
|
@@ -4088,13 +4529,13 @@ var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
|
|
|
4088
4529
|
var WORKOUT_PILL_DELOAD = primitiveRamps.magenta[600];
|
|
4089
4530
|
|
|
4090
4531
|
// src/components/custom/Workout/MesoStatusCard.tsx
|
|
4091
|
-
var
|
|
4092
|
-
var BRAND_PRIMARY5 =
|
|
4532
|
+
var t5 = getSemanticColors("dark");
|
|
4533
|
+
var BRAND_PRIMARY5 = t5["brand-primary"];
|
|
4093
4534
|
var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
|
|
4094
4535
|
var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
|
|
4095
|
-
var SUCCESS =
|
|
4096
|
-
var WARNING =
|
|
4097
|
-
var ERROR =
|
|
4536
|
+
var SUCCESS = t5["status-success"];
|
|
4537
|
+
var WARNING = t5["status-warning"];
|
|
4538
|
+
var ERROR = t5["status-error"];
|
|
4098
4539
|
var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY5, BRAND_PRIMARY_LIGHT];
|
|
4099
4540
|
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
4100
4541
|
var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(46,213,115,0.25) 0%, rgba(249,180,21,0.25) 50%, rgba(209,67,67,0.25) 100%)";
|
|
@@ -4454,9 +4895,9 @@ function MesoStatusCard({
|
|
|
4454
4895
|
var sem = getSemanticColors("dark");
|
|
4455
4896
|
var BRAND_PRIMARY6 = sem["brand-primary"];
|
|
4456
4897
|
var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
|
|
4457
|
-
var
|
|
4898
|
+
var STATUS_SUCCESS2 = sem["status-success"];
|
|
4458
4899
|
var STATUS_ERROR2 = sem["status-error"];
|
|
4459
|
-
var
|
|
4900
|
+
var STATUS_WARNING2 = sem["status-warning"];
|
|
4460
4901
|
var GRID_LINE = "rgba(255,255,255,0.06)";
|
|
4461
4902
|
var SUCCESS_PILL_BG = "rgba(46,213,115,0.10)";
|
|
4462
4903
|
var SUCCESS_PILL_BORDER = "rgba(46,213,115,0.20)";
|
|
@@ -4465,8 +4906,8 @@ var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
|
|
|
4465
4906
|
var PLOT_LEFT = 26;
|
|
4466
4907
|
var TOOLTIP_WIDTH = 124;
|
|
4467
4908
|
function timeOf(dateStr) {
|
|
4468
|
-
const
|
|
4469
|
-
return Number.isNaN(
|
|
4909
|
+
const t11 = Date.parse(dateStr);
|
|
4910
|
+
return Number.isNaN(t11) ? 0 : t11;
|
|
4470
4911
|
}
|
|
4471
4912
|
function formatValue(value) {
|
|
4472
4913
|
return `${Math.round(value)}`;
|
|
@@ -4762,7 +5203,7 @@ function StrengthTrendChart({
|
|
|
4762
5203
|
left: c.x - 7,
|
|
4763
5204
|
top: c.y - 20,
|
|
4764
5205
|
fontSize: 12,
|
|
4765
|
-
color:
|
|
5206
|
+
color: STATUS_WARNING2
|
|
4766
5207
|
},
|
|
4767
5208
|
children: "\u2605"
|
|
4768
5209
|
},
|
|
@@ -4855,7 +5296,7 @@ function StrengthTrendChart({
|
|
|
4855
5296
|
marginTop: 1,
|
|
4856
5297
|
fontSize: 10,
|
|
4857
5298
|
fontFamily: "Inter, sans-serif",
|
|
4858
|
-
color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ?
|
|
5299
|
+
color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
4859
5300
|
},
|
|
4860
5301
|
children: `${selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? "+" : "-"}${Math.abs(
|
|
4861
5302
|
selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm
|
|
@@ -4911,7 +5352,7 @@ function StrengthTrendChart({
|
|
|
4911
5352
|
fontSize: 11,
|
|
4912
5353
|
fontFamily: "Inter, sans-serif",
|
|
4913
5354
|
fontWeight: "600",
|
|
4914
|
-
color: trend.positive ?
|
|
5355
|
+
color: trend.positive ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
4915
5356
|
},
|
|
4916
5357
|
children: trendText
|
|
4917
5358
|
}
|
|
@@ -4945,7 +5386,7 @@ function StrengthTrendChart({
|
|
|
4945
5386
|
/* @__PURE__ */ jsx(Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Projected" })
|
|
4946
5387
|
] }),
|
|
4947
5388
|
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
4948
|
-
/* @__PURE__ */ jsx(Text, { style: { fontSize: 12, color:
|
|
5389
|
+
/* @__PURE__ */ jsx(Text, { style: { fontSize: 12, color: STATUS_WARNING2 }, children: "\u2605" }),
|
|
4949
5390
|
/* @__PURE__ */ jsx(Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "PR" })
|
|
4950
5391
|
] })
|
|
4951
5392
|
]
|
|
@@ -4955,10 +5396,10 @@ function StrengthTrendChart({
|
|
|
4955
5396
|
}
|
|
4956
5397
|
);
|
|
4957
5398
|
}
|
|
4958
|
-
var
|
|
4959
|
-
var
|
|
4960
|
-
var
|
|
4961
|
-
var STATUS_INFO =
|
|
5399
|
+
var t6 = getSemanticColors("dark");
|
|
5400
|
+
var STATUS_SUCCESS3 = t6["status-success"];
|
|
5401
|
+
var STATUS_WARNING3 = t6["status-warning"];
|
|
5402
|
+
var STATUS_INFO = t6["status-info"];
|
|
4962
5403
|
var DOT_BORDER = "#F3F4F6";
|
|
4963
5404
|
var BAND_FILL = "rgba(46,213,115,0.1)";
|
|
4964
5405
|
var BAND_EDGE = "rgba(46,213,115,0.45)";
|
|
@@ -4970,8 +5411,8 @@ var PADDING_BOTTOM = 16;
|
|
|
4970
5411
|
var COLUMN_STEP = 4;
|
|
4971
5412
|
var DOT_SIZE = 8;
|
|
4972
5413
|
var DOT_COLORS = {
|
|
4973
|
-
within:
|
|
4974
|
-
above:
|
|
5414
|
+
within: STATUS_SUCCESS3,
|
|
5415
|
+
above: STATUS_WARNING3,
|
|
4975
5416
|
below: STATUS_INFO
|
|
4976
5417
|
};
|
|
4977
5418
|
var STATUS_PHRASES = {
|
|
@@ -5001,8 +5442,8 @@ function interpEdge(pixels, x, key) {
|
|
|
5001
5442
|
const a = pixels[i];
|
|
5002
5443
|
const b = pixels[i + 1];
|
|
5003
5444
|
if (x >= a.x && x <= b.x) {
|
|
5004
|
-
const
|
|
5005
|
-
return a[key] +
|
|
5445
|
+
const t11 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
|
|
5446
|
+
return a[key] + t11 * (b[key] - a[key]);
|
|
5006
5447
|
}
|
|
5007
5448
|
}
|
|
5008
5449
|
return pixels[pixels.length - 1][key];
|
|
@@ -5196,8 +5637,8 @@ function CapacityBandChart({
|
|
|
5196
5637
|
projection && /* @__PURE__ */ jsxs(View, { testID: "capacity-band-chart-projection", children: [
|
|
5197
5638
|
renderColumns(buildColumns2(trainingPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
|
|
5198
5639
|
renderColumns(buildColumns2(restPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
|
|
5199
|
-
renderEdges(buildEdges(trainingPixels, "yHigh"),
|
|
5200
|
-
renderEdges(buildEdges(trainingPixels, "yLow"),
|
|
5640
|
+
renderEdges(buildEdges(trainingPixels, "yHigh"), STATUS_SUCCESS3, true, "capacity-band-chart-projection-training"),
|
|
5641
|
+
renderEdges(buildEdges(trainingPixels, "yLow"), STATUS_SUCCESS3, true, "capacity-band-chart-projection-training"),
|
|
5201
5642
|
renderEdges(buildEdges(restPixels, "yHigh"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
|
|
5202
5643
|
renderEdges(buildEdges(restPixels, "yLow"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
|
|
5203
5644
|
/* @__PURE__ */ jsx(
|
|
@@ -5209,7 +5650,7 @@ function CapacityBandChart({
|
|
|
5209
5650
|
top: trainingPixels[trainingPixels.length - 1]?.yHigh - 12,
|
|
5210
5651
|
fontSize: 9,
|
|
5211
5652
|
fontFamily: "Inter, sans-serif",
|
|
5212
|
-
color:
|
|
5653
|
+
color: STATUS_SUCCESS3
|
|
5213
5654
|
},
|
|
5214
5655
|
testID: "capacity-band-chart-projection-training-label",
|
|
5215
5656
|
children: "Training"
|
|
@@ -6041,7 +6482,7 @@ function Badge({
|
|
|
6041
6482
|
}
|
|
6042
6483
|
);
|
|
6043
6484
|
}
|
|
6044
|
-
var
|
|
6485
|
+
var t7 = getSemanticColors("dark");
|
|
6045
6486
|
var statusBgColors = {
|
|
6046
6487
|
completed: "rgba(46,213,115,0.15)",
|
|
6047
6488
|
current: "rgba(255,121,0,0.15)",
|
|
@@ -6059,9 +6500,9 @@ var statusBorderStyles = {
|
|
|
6059
6500
|
deload: { borderWidth: 1, borderColor: "rgba(186,41,150,0.3)" }
|
|
6060
6501
|
};
|
|
6061
6502
|
var textColors = {
|
|
6062
|
-
completed:
|
|
6063
|
-
current:
|
|
6064
|
-
next:
|
|
6503
|
+
completed: t7["status-success"],
|
|
6504
|
+
current: t7["brand-primary"],
|
|
6505
|
+
next: t7["brand-primary"],
|
|
6065
6506
|
upcoming: "#6B7280",
|
|
6066
6507
|
missed: "rgba(209,67,67,0.7)",
|
|
6067
6508
|
deload: WORKOUT_PILL_DELOAD
|
|
@@ -6194,19 +6635,19 @@ function WorkoutPill({
|
|
|
6194
6635
|
}
|
|
6195
6636
|
return pill;
|
|
6196
6637
|
}
|
|
6197
|
-
var
|
|
6638
|
+
var t8 = getSemanticColors("dark");
|
|
6198
6639
|
var TRACK_BG = "#333333";
|
|
6199
6640
|
var LABEL_COLOR = "#6B7280";
|
|
6200
6641
|
var TARGET_LINE_COLOR = "rgba(33, 150, 243, 0.5)";
|
|
6201
6642
|
var AT_TARGET_GLOW = "0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)";
|
|
6202
6643
|
var ZONE = {
|
|
6203
|
-
building:
|
|
6644
|
+
building: t8["status-success"],
|
|
6204
6645
|
// below target ramp-up
|
|
6205
|
-
approaching:
|
|
6646
|
+
approaching: t8["status-warning"],
|
|
6206
6647
|
// nearing target
|
|
6207
|
-
target:
|
|
6648
|
+
target: t8["brand-primary"],
|
|
6208
6649
|
// exactly at target
|
|
6209
|
-
over1:
|
|
6650
|
+
over1: t8["status-error"],
|
|
6210
6651
|
// mild over-target
|
|
6211
6652
|
over2: WORKOUT_TOKENS.intensity.over2,
|
|
6212
6653
|
// moderate over-target
|
|
@@ -6629,13 +7070,13 @@ function MesoCard({
|
|
|
6629
7070
|
}
|
|
6630
7071
|
) });
|
|
6631
7072
|
}
|
|
6632
|
-
var
|
|
7073
|
+
var t9 = getSemanticColors("dark");
|
|
6633
7074
|
var dotColorMap = {
|
|
6634
7075
|
untrained: "#2C2C2C",
|
|
6635
|
-
behind:
|
|
6636
|
-
ontrack:
|
|
6637
|
-
target:
|
|
6638
|
-
over:
|
|
7076
|
+
behind: t9["brand-secondary"],
|
|
7077
|
+
ontrack: t9["status-success"],
|
|
7078
|
+
target: t9["brand-primary"],
|
|
7079
|
+
over: t9["status-error"]
|
|
6639
7080
|
};
|
|
6640
7081
|
function MuscleGroupChip({
|
|
6641
7082
|
name,
|
|
@@ -6709,10 +7150,10 @@ function MuscleGroupChip({
|
|
|
6709
7150
|
}
|
|
6710
7151
|
|
|
6711
7152
|
// src/components/custom/Workout/WorkoutCard.tsx
|
|
6712
|
-
var
|
|
7153
|
+
var t10 = getSemanticColors("dark");
|
|
6713
7154
|
var COLORS = {
|
|
6714
|
-
statusSuccess:
|
|
6715
|
-
brandPrimary:
|
|
7155
|
+
statusSuccess: t10["status-success"],
|
|
7156
|
+
brandPrimary: t10["brand-primary"],
|
|
6716
7157
|
borderDefault: "#1F1F1F",
|
|
6717
7158
|
brandPrimarySubtle: "rgba(255,121,0,0.06)"
|
|
6718
7159
|
};
|