@dubsdotapp/expo 0.5.6 → 0.5.7

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
@@ -1378,10 +1378,12 @@ interface JoinGameSheetProps {
1378
1378
  onError?: (error: Error) => void;
1379
1379
  /** Called when the user taps a team card (useful for sound/haptics) */
1380
1380
  onTeamSelect?: (team: 'home' | 'away') => void;
1381
+ /** Called when the join succeeds (useful for success sound/animation) */
1382
+ onJoinSuccess?: (result: JoinGameMutationResult) => void;
1381
1383
  /** Pool mode: hides team selection, auto-assigns team, shows "Join Pool" labels */
1382
1384
  isPoolModeEnabled?: boolean;
1383
1385
  }
1384
- declare function JoinGameSheet({ visible, onDismiss, game, ImageComponent, shortName, homeColor, awayColor, onSuccess, onError, onTeamSelect, isPoolModeEnabled, }: JoinGameSheetProps): react_jsx_runtime.JSX.Element;
1386
+ declare function JoinGameSheet({ visible, onDismiss, game, ImageComponent, shortName, homeColor, awayColor, onSuccess, onError, onTeamSelect, onJoinSuccess, isPoolModeEnabled, }: JoinGameSheetProps): react_jsx_runtime.JSX.Element;
1385
1387
 
1386
1388
  interface ClaimPrizeSheetProps {
1387
1389
  visible: boolean;
package/dist/index.d.ts CHANGED
@@ -1378,10 +1378,12 @@ interface JoinGameSheetProps {
1378
1378
  onError?: (error: Error) => void;
1379
1379
  /** Called when the user taps a team card (useful for sound/haptics) */
1380
1380
  onTeamSelect?: (team: 'home' | 'away') => void;
1381
+ /** Called when the join succeeds (useful for success sound/animation) */
1382
+ onJoinSuccess?: (result: JoinGameMutationResult) => void;
1381
1383
  /** Pool mode: hides team selection, auto-assigns team, shows "Join Pool" labels */
1382
1384
  isPoolModeEnabled?: boolean;
1383
1385
  }
1384
- declare function JoinGameSheet({ visible, onDismiss, game, ImageComponent, shortName, homeColor, awayColor, onSuccess, onError, onTeamSelect, isPoolModeEnabled, }: JoinGameSheetProps): react_jsx_runtime.JSX.Element;
1386
+ declare function JoinGameSheet({ visible, onDismiss, game, ImageComponent, shortName, homeColor, awayColor, onSuccess, onError, onTeamSelect, onJoinSuccess, isPoolModeEnabled, }: JoinGameSheetProps): react_jsx_runtime.JSX.Element;
1385
1387
 
1386
1388
  interface ClaimPrizeSheetProps {
1387
1389
  visible: boolean;
package/dist/index.js CHANGED
@@ -5351,6 +5351,13 @@ var STATUS_LABELS3 = {
5351
5351
  success: "Joined!"
5352
5352
  };
5353
5353
  var CUSTOM_GAME_MODE = 6;
5354
+ function formatSol(n) {
5355
+ return parseFloat(n.toFixed(9)).toString();
5356
+ }
5357
+ function toPng(url) {
5358
+ if (!url) return null;
5359
+ return url.replace("/svg?", "/png?");
5360
+ }
5354
5361
  function JoinGameSheet({
5355
5362
  visible,
5356
5363
  onDismiss,
@@ -5362,6 +5369,7 @@ function JoinGameSheet({
5362
5369
  onSuccess,
5363
5370
  onError,
5364
5371
  onTeamSelect,
5372
+ onJoinSuccess,
5365
5373
  isPoolModeEnabled = false
5366
5374
  }) {
5367
5375
  const t = useDubsTheme();
@@ -5369,7 +5377,10 @@ function JoinGameSheet({
5369
5377
  const mutation = useJoinGame();
5370
5378
  const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
5371
5379
  const [selectedTeam, setSelectedTeam] = (0, import_react33.useState)(null);
5380
+ const [showSuccess, setShowSuccess] = (0, import_react33.useState)(false);
5372
5381
  const overlayOpacity = (0, import_react33.useRef)(new import_react_native19.Animated.Value(0)).current;
5382
+ const successScale = (0, import_react33.useRef)(new import_react_native19.Animated.Value(0)).current;
5383
+ const successOpacity = (0, import_react33.useRef)(new import_react_native19.Animated.Value(0)).current;
5373
5384
  (0, import_react33.useEffect)(() => {
5374
5385
  import_react_native19.Animated.timing(overlayOpacity, {
5375
5386
  toValue: visible ? 1 : 0,
@@ -5380,15 +5391,26 @@ function JoinGameSheet({
5380
5391
  (0, import_react33.useEffect)(() => {
5381
5392
  if (visible) {
5382
5393
  setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
5394
+ setShowSuccess(false);
5395
+ successScale.setValue(0);
5396
+ successOpacity.setValue(0);
5383
5397
  mutation.reset();
5384
5398
  }
5385
5399
  }, [visible]);
5386
5400
  (0, import_react33.useEffect)(() => {
5387
5401
  if (mutation.status === "success" && mutation.data) {
5402
+ setShowSuccess(true);
5388
5403
  onSuccess?.(mutation.data);
5404
+ onJoinSuccess?.(mutation.data);
5405
+ import_react_native19.Animated.parallel([
5406
+ import_react_native19.Animated.spring(successScale, { toValue: 1, friction: 4, tension: 80, useNativeDriver: true }),
5407
+ import_react_native19.Animated.timing(successOpacity, { toValue: 1, duration: 300, useNativeDriver: true })
5408
+ ]).start();
5389
5409
  const timer = setTimeout(() => {
5390
- onDismiss();
5391
- }, 1500);
5410
+ import_react_native19.Animated.timing(successOpacity, { toValue: 0, duration: 300, useNativeDriver: true }).start(() => {
5411
+ onDismiss();
5412
+ });
5413
+ }, 2500);
5392
5414
  return () => clearTimeout(timer);
5393
5415
  }
5394
5416
  }, [mutation.status, mutation.data]);
@@ -5411,7 +5433,7 @@ function JoinGameSheet({
5411
5433
  }), [totalPool, homePool, awayPool, bettors]);
5412
5434
  const poolAfterJoin = totalPool + buyIn;
5413
5435
  const selectedOdds = selectedTeam === "home" ? homeOdds : selectedTeam === "away" ? awayOdds : "\u2014";
5414
- const potentialWinnings = selectedOdds !== "\u2014" ? (parseFloat(selectedOdds) * buyIn).toFixed(4) : "\u2014";
5436
+ const potentialWinnings = selectedOdds !== "\u2014" ? formatSol(parseFloat(selectedOdds) * buyIn) : "\u2014";
5415
5437
  const homeName = shortName ? shortName(opponents[0]?.name) : opponents[0]?.name || "Home";
5416
5438
  const awayName = shortName ? shortName(opponents[1]?.name) : opponents[1]?.name || "Away";
5417
5439
  const selectedName = selectedTeam === "home" ? homeName : selectedTeam === "away" ? awayName : "\u2014";
@@ -5444,6 +5466,15 @@ function JoinGameSheet({
5444
5466
  onRequestClose: onDismiss,
5445
5467
  children: [
5446
5468
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Animated.View, { style: [styles13.overlay, { opacity: overlayOpacity }], children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.TouchableOpacity, { style: styles13.overlayTap, activeOpacity: 1, onPress: onDismiss }) }),
5469
+ showSuccess && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.View, { style: styles13.successOverlay, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Animated.View, { style: [styles13.successContent, { opacity: successOpacity, transform: [{ scale: successScale }] }], children: [
5470
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: styles13.successEmoji, children: "\u{1F389}" }),
5471
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: styles13.successTitle, children: "You're in!" }),
5472
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Text, { style: styles13.successSub, children: [
5473
+ formatSol(buyIn),
5474
+ " SOL on ",
5475
+ selectedName
5476
+ ] })
5477
+ ] }) }),
5447
5478
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5448
5479
  import_react_native19.KeyboardAvoidingView,
5449
5480
  {
@@ -5455,6 +5486,24 @@ function JoinGameSheet({
5455
5486
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.headerTitle, { color: t.text }], children: isPoolModeEnabled ? "Join Pool" : "Join Game" }),
5456
5487
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.TouchableOpacity, { onPress: onDismiss, activeOpacity: 0.8, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.closeButton, { color: t.textMuted }], children: "\u2715" }) })
5457
5488
  ] }),
5489
+ bettors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.bettorsSection, children: [
5490
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Text, { style: [styles13.bettorsLabel, { color: t.textMuted }], children: [
5491
+ bettors.length,
5492
+ " ",
5493
+ bettors.length === 1 ? "player" : "players",
5494
+ " in this game"
5495
+ ] }),
5496
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.bettorsRow, children: [
5497
+ bettors.slice(0, 6).map((b, i) => {
5498
+ const pngUrl = toPng(b.avatar);
5499
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.View, { style: [styles13.bettorCircle, { backgroundColor: ["#EF4444", "#3B82F6", "#22C55E", "#F59E0B", "#A855F7", "#EC4899"][i % 6] }], children: pngUrl ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Image, { source: { uri: pngUrl }, style: styles13.bettorImg }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: styles13.bettorInitial, children: (b.username ?? b.wallet).charAt(0).toUpperCase() }) }, b.wallet);
5500
+ }),
5501
+ bettors.length > 6 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.View, { style: [styles13.bettorCircle, { backgroundColor: "#2C2C2E" }], children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Text, { style: styles13.bettorOverflow, children: [
5502
+ "+",
5503
+ bettors.length - 6
5504
+ ] }) })
5505
+ ] })
5506
+ ] }),
5458
5507
  !isCustomGame && !isPoolModeEnabled && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.section, children: [
5459
5508
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.sectionLabel, { color: t.textSecondary }], children: "Pick Your Side" }),
5460
5509
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.teamsRow, children: [
@@ -5498,7 +5547,7 @@ function JoinGameSheet({
5498
5547
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.summaryRow, children: [
5499
5548
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.summaryLabel, { color: t.textMuted }], children: "Buy-in" }),
5500
5549
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Text, { style: [styles13.summaryValue, { color: t.text }], children: [
5501
- buyIn,
5550
+ formatSol(buyIn),
5502
5551
  " SOL"
5503
5552
  ] })
5504
5553
  ] }),
@@ -5512,7 +5561,7 @@ function JoinGameSheet({
5512
5561
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.summaryRow, children: [
5513
5562
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.summaryLabel, { color: t.textMuted }], children: "Current pot" }),
5514
5563
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Text, { style: [styles13.summaryValue, { color: t.success }], children: [
5515
- totalPool,
5564
+ formatSol(totalPool),
5516
5565
  " SOL"
5517
5566
  ] })
5518
5567
  ] })
@@ -5525,7 +5574,7 @@ function JoinGameSheet({
5525
5574
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.summaryRow, children: [
5526
5575
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.summaryLabel, { color: t.textMuted }], children: "Total pool" }),
5527
5576
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.Text, { style: [styles13.summaryValue, { color: t.text }], children: [
5528
- poolAfterJoin,
5577
+ formatSol(poolAfterJoin),
5529
5578
  " SOL"
5530
5579
  ] })
5531
5580
  ] }),
@@ -5551,7 +5600,7 @@ function JoinGameSheet({
5551
5600
  children: isMutating ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native19.View, { style: styles13.ctaLoading, children: [
5552
5601
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
5553
5602
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: styles13.ctaText, children: statusLabel })
5554
- ] }) : mutation.status === "success" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: styles13.ctaText, children: isPoolModeEnabled ? "Joined!" : STATUS_LABELS3.success }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.ctaText, !canJoin && { opacity: 0.5 }], children: alreadyJoined ? "Already Joined" : isPoolModeEnabled ? `Join Pool \u2014 ${buyIn} SOL` : selectedTeam ? `Join Game \u2014 ${buyIn} SOL` : "Pick a side to join" })
5603
+ ] }) : mutation.status === "success" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: styles13.ctaText, children: isPoolModeEnabled ? "Joined!" : STATUS_LABELS3.success }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Text, { style: [styles13.ctaText, !canJoin && { opacity: 0.5 }], children: alreadyJoined ? "Already Joined" : isPoolModeEnabled ? `Join Pool \u2014 ${formatSol(buyIn)} SOL` : selectedTeam ? `Join Game \u2014 ${formatSol(buyIn)} SOL` : "Pick a side to join" })
5555
5604
  }
5556
5605
  )
5557
5606
  ] }) })
@@ -5644,6 +5693,67 @@ var styles13 = import_react_native19.StyleSheet.create({
5644
5693
  fontSize: 20,
5645
5694
  padding: 4
5646
5695
  },
5696
+ // Bettors row
5697
+ bettorsSection: {
5698
+ paddingBottom: 12,
5699
+ gap: 8
5700
+ },
5701
+ bettorsLabel: {
5702
+ fontSize: 12,
5703
+ fontWeight: "600"
5704
+ },
5705
+ bettorsRow: {
5706
+ flexDirection: "row",
5707
+ alignItems: "center",
5708
+ gap: 4
5709
+ },
5710
+ bettorCircle: {
5711
+ width: 28,
5712
+ height: 28,
5713
+ borderRadius: 14,
5714
+ alignItems: "center",
5715
+ justifyContent: "center",
5716
+ overflow: "hidden"
5717
+ },
5718
+ bettorImg: {
5719
+ width: 28,
5720
+ height: 28,
5721
+ borderRadius: 14
5722
+ },
5723
+ bettorInitial: {
5724
+ color: "#FFF",
5725
+ fontSize: 11,
5726
+ fontWeight: "800"
5727
+ },
5728
+ bettorOverflow: {
5729
+ color: "#8E8E93",
5730
+ fontSize: 10,
5731
+ fontWeight: "700"
5732
+ },
5733
+ // Success overlay
5734
+ successOverlay: {
5735
+ ...import_react_native19.StyleSheet.absoluteFillObject,
5736
+ zIndex: 100,
5737
+ alignItems: "center",
5738
+ justifyContent: "center",
5739
+ backgroundColor: "rgba(0,0,0,0.85)"
5740
+ },
5741
+ successContent: {
5742
+ alignItems: "center",
5743
+ gap: 12
5744
+ },
5745
+ successEmoji: {
5746
+ fontSize: 64
5747
+ },
5748
+ successTitle: {
5749
+ color: "#FFFFFF",
5750
+ fontSize: 28,
5751
+ fontWeight: "900"
5752
+ },
5753
+ successSub: {
5754
+ color: "#8E8E93",
5755
+ fontSize: 16
5756
+ },
5647
5757
  section: {
5648
5758
  gap: 12,
5649
5759
  paddingTop: 8