@digilogiclabs/saas-factory-ui 2.5.0 → 2.6.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.
@@ -5551,8 +5551,14 @@ interface RandomPlayerPickerProps {
5551
5551
  darkMode?: boolean;
5552
5552
  /** Wheel diameter in px. Default 380. */
5553
5553
  size?: number;
5554
- /** Called when a winner is locked in. */
5555
- onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[]) => void;
5554
+ /**
5555
+ * Called when a winner is locked in. `info.lastStanding` is true for
5556
+ * the automatic final pick of a draft — the survivor promoted when
5557
+ * pops drain the pool to one.
5558
+ */
5559
+ onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[], info?: {
5560
+ lastStanding: boolean;
5561
+ }) => void;
5556
5562
  /** Fired the moment a spin begins (before the animation). */
5557
5563
  onSpinStart?: () => void;
5558
5564
  /**
@@ -5551,8 +5551,14 @@ interface RandomPlayerPickerProps {
5551
5551
  darkMode?: boolean;
5552
5552
  /** Wheel diameter in px. Default 380. */
5553
5553
  size?: number;
5554
- /** Called when a winner is locked in. */
5555
- onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[]) => void;
5554
+ /**
5555
+ * Called when a winner is locked in. `info.lastStanding` is true for
5556
+ * the automatic final pick of a draft — the survivor promoted when
5557
+ * pops drain the pool to one.
5558
+ */
5559
+ onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[], info?: {
5560
+ lastStanding: boolean;
5561
+ }) => void;
5556
5562
  /** Fired the moment a spin begins (before the animation). */
5557
5563
  onSpinStart?: () => void;
5558
5564
  /**
package/dist/web/index.js CHANGED
@@ -33925,7 +33925,20 @@ function RandomPlayerPicker({
33925
33925
  }
33926
33926
  }
33927
33927
  const activeN = activePool.length;
33928
- if (activeN < 2) return;
33928
+ if (activeN < 2) {
33929
+ if (removeWinnersRef.current && activePool.length === 1 && history.length > 0) {
33930
+ const survivor = activePool[0];
33931
+ if (survivor) {
33932
+ const promoted = [survivor, ...history].slice(0, 20);
33933
+ setPool([]);
33934
+ setWinner(survivor);
33935
+ setRevealKey((k) => k + 1);
33936
+ setHistory(promoted);
33937
+ onPick?.(survivor, promoted, { lastStanding: true });
33938
+ }
33939
+ }
33940
+ return;
33941
+ }
33929
33942
  const activeAnglePerWedge = 2 * Math.PI / activeN;
33930
33943
  const activeRotation = rotation;
33931
33944
  const activeReelY = reelY;
@@ -34090,8 +34103,19 @@ function RandomPlayerPicker({
34090
34103
  popTimer.current = null;
34091
34104
  pendingPopIdxRef.current = null;
34092
34105
  if (!removeWinnersRef.current) return;
34093
- setPool((p) => p.filter((_, i) => i !== finalWinnerIdx));
34094
- if (activePool.length - 1 >= 2) setWinner(null);
34106
+ const survivors = activePool.filter((_, i) => i !== finalWinnerIdx);
34107
+ const survivor = survivors.length === 1 ? survivors[0] : void 0;
34108
+ if (survivor) {
34109
+ const promoted = [survivor, ...nextHistory].slice(0, 20);
34110
+ setPool([]);
34111
+ setWinner(survivor);
34112
+ setRevealKey((k) => k + 1);
34113
+ setHistory(promoted);
34114
+ onPick?.(survivor, promoted, { lastStanding: true });
34115
+ } else {
34116
+ setPool(survivors);
34117
+ setWinner(null);
34118
+ }
34095
34119
  setRotation(0);
34096
34120
  setReelY(0);
34097
34121
  }, 2800);
@@ -38693,6 +38717,33 @@ function GameTimer({
38693
38717
  if (rafRef.current) cancelAnimationFrame(rafRef.current);
38694
38718
  };
38695
38719
  }, [running, tick]);
38720
+ (0, import_react76.useEffect)(() => {
38721
+ if (!running || mode !== "countdown") return;
38722
+ let timeoutId = null;
38723
+ const disarm = () => {
38724
+ if (timeoutId !== null) {
38725
+ clearTimeout(timeoutId);
38726
+ timeoutId = null;
38727
+ }
38728
+ };
38729
+ const arm = () => {
38730
+ disarm();
38731
+ const remainingUntilDone = durationMs - elapsedRef.current;
38732
+ if (remainingUntilDone > 0) {
38733
+ timeoutId = setTimeout(tick, remainingUntilDone + 50);
38734
+ }
38735
+ };
38736
+ const onVisibility = () => {
38737
+ if (document.hidden) arm();
38738
+ else disarm();
38739
+ };
38740
+ document.addEventListener("visibilitychange", onVisibility);
38741
+ if (document.hidden) arm();
38742
+ return () => {
38743
+ disarm();
38744
+ document.removeEventListener("visibilitychange", onVisibility);
38745
+ };
38746
+ }, [running, mode, durationMs, tick]);
38696
38747
  const start = (0, import_react76.useCallback)(() => {
38697
38748
  if (completed && mode === "countdown") return;
38698
38749
  setRunning(true);