@digilogiclabs/saas-factory-ui 2.5.0 → 2.7.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 CHANGED
@@ -5015,8 +5015,14 @@ interface RandomPlayerPickerProps {
5015
5015
  darkMode?: boolean;
5016
5016
  /** Wheel diameter in px. Default 380. */
5017
5017
  size?: number;
5018
- /** Called when a winner is locked in. */
5019
- onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[]) => void;
5018
+ /**
5019
+ * Called when a winner is locked in. `info.lastStanding` is true for
5020
+ * the automatic final pick of a draft — the survivor promoted when
5021
+ * pops drain the pool to one.
5022
+ */
5023
+ onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[], info?: {
5024
+ lastStanding: boolean;
5025
+ }) => void;
5020
5026
  /** Fired the moment a spin begins (before the animation). */
5021
5027
  onSpinStart?: () => void;
5022
5028
  /**
package/dist/index.d.ts CHANGED
@@ -5015,8 +5015,14 @@ interface RandomPlayerPickerProps {
5015
5015
  darkMode?: boolean;
5016
5016
  /** Wheel diameter in px. Default 380. */
5017
5017
  size?: number;
5018
- /** Called when a winner is locked in. */
5019
- onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[]) => void;
5018
+ /**
5019
+ * Called when a winner is locked in. `info.lastStanding` is true for
5020
+ * the automatic final pick of a draft — the survivor promoted when
5021
+ * pops drain the pool to one.
5022
+ */
5023
+ onPick?: (winner: RandomPlayerParticipant, history: RandomPlayerParticipant[], info?: {
5024
+ lastStanding: boolean;
5025
+ }) => void;
5020
5026
  /** Fired the moment a spin begins (before the animation). */
5021
5027
  onSpinStart?: () => void;
5022
5028
  /**
package/dist/index.js CHANGED
@@ -34079,7 +34079,20 @@ function RandomPlayerPicker({
34079
34079
  }
34080
34080
  }
34081
34081
  const activeN = activePool.length;
34082
- if (activeN < 2) return;
34082
+ if (activeN < 2) {
34083
+ if (removeWinnersRef.current && activePool.length === 1 && history.length > 0) {
34084
+ const survivor = activePool[0];
34085
+ if (survivor) {
34086
+ const promoted = [survivor, ...history].slice(0, 20);
34087
+ setPool([]);
34088
+ setWinner(survivor);
34089
+ setRevealKey((k) => k + 1);
34090
+ setHistory(promoted);
34091
+ onPick?.(survivor, promoted, { lastStanding: true });
34092
+ }
34093
+ }
34094
+ return;
34095
+ }
34083
34096
  const activeAnglePerWedge = 2 * Math.PI / activeN;
34084
34097
  const activeRotation = rotation;
34085
34098
  const activeReelY = reelY;
@@ -34244,8 +34257,19 @@ function RandomPlayerPicker({
34244
34257
  popTimer.current = null;
34245
34258
  pendingPopIdxRef.current = null;
34246
34259
  if (!removeWinnersRef.current) return;
34247
- setPool((p) => p.filter((_, i) => i !== finalWinnerIdx));
34248
- if (activePool.length - 1 >= 2) setWinner(null);
34260
+ const survivors = activePool.filter((_, i) => i !== finalWinnerIdx);
34261
+ const survivor = survivors.length === 1 ? survivors[0] : void 0;
34262
+ if (survivor) {
34263
+ const promoted = [survivor, ...nextHistory].slice(0, 20);
34264
+ setPool([]);
34265
+ setWinner(survivor);
34266
+ setRevealKey((k) => k + 1);
34267
+ setHistory(promoted);
34268
+ onPick?.(survivor, promoted, { lastStanding: true });
34269
+ } else {
34270
+ setPool(survivors);
34271
+ setWinner(null);
34272
+ }
34249
34273
  setRotation(0);
34250
34274
  setReelY(0);
34251
34275
  }, 2800);
@@ -38847,6 +38871,33 @@ function GameTimer({
38847
38871
  if (rafRef.current) cancelAnimationFrame(rafRef.current);
38848
38872
  };
38849
38873
  }, [running, tick]);
38874
+ (0, import_react74.useEffect)(() => {
38875
+ if (!running || mode !== "countdown") return;
38876
+ let timeoutId = null;
38877
+ const disarm = () => {
38878
+ if (timeoutId !== null) {
38879
+ clearTimeout(timeoutId);
38880
+ timeoutId = null;
38881
+ }
38882
+ };
38883
+ const arm = () => {
38884
+ disarm();
38885
+ const remainingUntilDone = durationMs - elapsedRef.current;
38886
+ if (remainingUntilDone > 0) {
38887
+ timeoutId = setTimeout(tick, remainingUntilDone + 50);
38888
+ }
38889
+ };
38890
+ const onVisibility = () => {
38891
+ if (document.hidden) arm();
38892
+ else disarm();
38893
+ };
38894
+ document.addEventListener("visibilitychange", onVisibility);
38895
+ if (document.hidden) arm();
38896
+ return () => {
38897
+ disarm();
38898
+ document.removeEventListener("visibilitychange", onVisibility);
38899
+ };
38900
+ }, [running, mode, durationMs, tick]);
38850
38901
  const start = (0, import_react74.useCallback)(() => {
38851
38902
  if (completed && mode === "countdown") return;
38852
38903
  setRunning(true);