@dubsdotapp/expo 0.5.15 → 0.5.17

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.mjs CHANGED
@@ -645,7 +645,7 @@ function createSecureStoreStorage() {
645
645
  }
646
646
 
647
647
  // src/provider.tsx
648
- import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useCallback as useCallback21, useState as useState23, useEffect as useEffect15 } from "react";
648
+ import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useCallback as useCallback22, useState as useState24, useEffect as useEffect16 } from "react";
649
649
 
650
650
  // src/ui/theme.ts
651
651
  import { createContext, useContext } from "react";
@@ -1710,7 +1710,7 @@ function ManagedWalletProvider({
1710
1710
  }
1711
1711
 
1712
1712
  // src/ui/AuthGate.tsx
1713
- import React2, { useState as useState22, useEffect as useEffect14, useRef as useRef6, useCallback as useCallback20 } from "react";
1713
+ import React2, { useState as useState23, useEffect as useEffect15, useRef as useRef6, useCallback as useCallback21 } from "react";
1714
1714
  import {
1715
1715
  View as View3,
1716
1716
  Text as Text3,
@@ -2441,25 +2441,51 @@ function useHighlights(league, limit = 8) {
2441
2441
  return { data, loading, error, refetch: fetchData };
2442
2442
  }
2443
2443
 
2444
+ // src/hooks/useShorts.ts
2445
+ import { useState as useState15, useEffect as useEffect10, useCallback as useCallback14 } from "react";
2446
+ function useShorts(league = "NBA", limit = 20) {
2447
+ const { client } = useDubs();
2448
+ const [data, setData] = useState15(null);
2449
+ const [loading, setLoading] = useState15(true);
2450
+ const [error, setError] = useState15(null);
2451
+ const fetchData = useCallback14(async () => {
2452
+ setLoading(true);
2453
+ setError(null);
2454
+ try {
2455
+ const qs = new URLSearchParams({ league, limit: String(limit) });
2456
+ const res = await client.request("GET", `/shorts?${qs.toString()}`);
2457
+ setData(res.videos || []);
2458
+ } catch (err) {
2459
+ setError(err instanceof Error ? err : new Error(String(err)));
2460
+ } finally {
2461
+ setLoading(false);
2462
+ }
2463
+ }, [client, league, limit]);
2464
+ useEffect10(() => {
2465
+ fetchData();
2466
+ }, [fetchData]);
2467
+ return { data, loading, error, refetch: fetchData };
2468
+ }
2469
+
2444
2470
  // src/hooks/usePushNotifications.ts
2445
- import { useState as useState15, useCallback as useCallback14, useRef as useRef3, useMemo, useEffect as useEffect10 } from "react";
2471
+ import { useState as useState16, useCallback as useCallback15, useRef as useRef3, useMemo, useEffect as useEffect11 } from "react";
2446
2472
  import { Platform as Platform3 } from "react-native";
2447
2473
  function usePushNotifications() {
2448
2474
  const { client, appName, pushEnabled } = useDubs();
2449
2475
  const channelId = useMemo(() => appName.toLowerCase().replace(/[^a-z0-9-]/g, ""), [appName]);
2450
- const [hasPermission, setHasPermission] = useState15(false);
2451
- const [pushToken, setPushToken] = useState15(null);
2452
- const [loading, setLoading] = useState15(false);
2453
- const [error, setError] = useState15(null);
2476
+ const [hasPermission, setHasPermission] = useState16(false);
2477
+ const [pushToken, setPushToken] = useState16(null);
2478
+ const [loading, setLoading] = useState16(false);
2479
+ const [error, setError] = useState16(null);
2454
2480
  const registering = useRef3(false);
2455
- const getNotificationsModule = useCallback14(() => {
2481
+ const getNotificationsModule = useCallback15(() => {
2456
2482
  try {
2457
2483
  return __require("expo-notifications");
2458
2484
  } catch {
2459
2485
  return null;
2460
2486
  }
2461
2487
  }, []);
2462
- const getDeviceName = useCallback14(() => {
2488
+ const getDeviceName = useCallback15(() => {
2463
2489
  try {
2464
2490
  const Device = __require("expo-device");
2465
2491
  return Device.deviceName || null;
@@ -2467,7 +2493,7 @@ function usePushNotifications() {
2467
2493
  return null;
2468
2494
  }
2469
2495
  }, []);
2470
- const setupAndroidChannels = useCallback14((Notifications) => {
2496
+ const setupAndroidChannels = useCallback15((Notifications) => {
2471
2497
  if (Platform3.OS === "android") {
2472
2498
  Notifications.setNotificationChannelAsync(channelId || "default", {
2473
2499
  name: appName || "Default",
@@ -2477,7 +2503,7 @@ function usePushNotifications() {
2477
2503
  });
2478
2504
  }
2479
2505
  }, [channelId, appName]);
2480
- const registerTokenWithServer = useCallback14(async (token) => {
2506
+ const registerTokenWithServer = useCallback15(async (token) => {
2481
2507
  const deviceName = getDeviceName();
2482
2508
  await client.registerPushToken({
2483
2509
  token,
@@ -2485,7 +2511,7 @@ function usePushNotifications() {
2485
2511
  deviceName: deviceName || void 0
2486
2512
  });
2487
2513
  }, [client, getDeviceName]);
2488
- const register = useCallback14(async () => {
2514
+ const register = useCallback15(async () => {
2489
2515
  if (!pushEnabled) return false;
2490
2516
  if (registering.current) return false;
2491
2517
  registering.current = true;
@@ -2526,7 +2552,7 @@ function usePushNotifications() {
2526
2552
  return false;
2527
2553
  }
2528
2554
  }, [getNotificationsModule, registerTokenWithServer, setupAndroidChannels]);
2529
- const unregister = useCallback14(async () => {
2555
+ const unregister = useCallback15(async () => {
2530
2556
  if (!pushToken) return;
2531
2557
  try {
2532
2558
  await client.unregisterPushToken(pushToken);
@@ -2535,7 +2561,7 @@ function usePushNotifications() {
2535
2561
  console.error("[usePushNotifications] Unregister error:", err);
2536
2562
  }
2537
2563
  }, [client, pushToken]);
2538
- const restoreIfGranted = useCallback14(async () => {
2564
+ const restoreIfGranted = useCallback15(async () => {
2539
2565
  if (!pushEnabled) return;
2540
2566
  try {
2541
2567
  const Notifications = getNotificationsModule();
@@ -2554,7 +2580,7 @@ function usePushNotifications() {
2554
2580
  }
2555
2581
  }, [getNotificationsModule, registerTokenWithServer, setupAndroidChannels]);
2556
2582
  const didMount = useRef3(false);
2557
- useEffect10(() => {
2583
+ useEffect11(() => {
2558
2584
  if (didMount.current) return;
2559
2585
  didMount.current = true;
2560
2586
  const Notifications = getNotificationsModule();
@@ -2584,13 +2610,13 @@ function usePushNotifications() {
2584
2610
  }
2585
2611
 
2586
2612
  // src/hooks/useArcadePools.ts
2587
- import { useState as useState16, useEffect as useEffect11, useCallback as useCallback15 } from "react";
2613
+ import { useState as useState17, useEffect as useEffect12, useCallback as useCallback16 } from "react";
2588
2614
  function useArcadePools(gameSlug) {
2589
2615
  const { client } = useDubs();
2590
- const [pools, setPools] = useState16([]);
2591
- const [loading, setLoading] = useState16(false);
2592
- const [error, setError] = useState16(null);
2593
- const fetch2 = useCallback15(async () => {
2616
+ const [pools, setPools] = useState17([]);
2617
+ const [loading, setLoading] = useState17(false);
2618
+ const [error, setError] = useState17(null);
2619
+ const fetch2 = useCallback16(async () => {
2594
2620
  setLoading(true);
2595
2621
  setError(null);
2596
2622
  try {
@@ -2602,22 +2628,22 @@ function useArcadePools(gameSlug) {
2602
2628
  setLoading(false);
2603
2629
  }
2604
2630
  }, [client, gameSlug]);
2605
- useEffect11(() => {
2631
+ useEffect12(() => {
2606
2632
  fetch2();
2607
2633
  }, [fetch2]);
2608
2634
  return { pools, loading, error, refetch: fetch2 };
2609
2635
  }
2610
2636
 
2611
2637
  // src/hooks/useArcadePool.ts
2612
- import { useState as useState17, useEffect as useEffect12, useCallback as useCallback16 } from "react";
2638
+ import { useState as useState18, useEffect as useEffect13, useCallback as useCallback17 } from "react";
2613
2639
  function useArcadePool(poolId) {
2614
2640
  const { client } = useDubs();
2615
- const [pool, setPool] = useState17(null);
2616
- const [stats, setStats] = useState17(null);
2617
- const [leaderboard, setLeaderboard] = useState17([]);
2618
- const [loading, setLoading] = useState17(false);
2619
- const [error, setError] = useState17(null);
2620
- const fetch2 = useCallback16(async () => {
2641
+ const [pool, setPool] = useState18(null);
2642
+ const [stats, setStats] = useState18(null);
2643
+ const [leaderboard, setLeaderboard] = useState18([]);
2644
+ const [loading, setLoading] = useState18(false);
2645
+ const [error, setError] = useState18(null);
2646
+ const fetch2 = useCallback17(async () => {
2621
2647
  if (!poolId) return;
2622
2648
  setLoading(true);
2623
2649
  setError(null);
@@ -2635,22 +2661,22 @@ function useArcadePool(poolId) {
2635
2661
  setLoading(false);
2636
2662
  }
2637
2663
  }, [client, poolId]);
2638
- useEffect12(() => {
2664
+ useEffect13(() => {
2639
2665
  fetch2();
2640
2666
  }, [fetch2]);
2641
2667
  return { pool, stats, leaderboard, loading, error, refetch: fetch2 };
2642
2668
  }
2643
2669
 
2644
2670
  // src/hooks/useArcadeGame.ts
2645
- import { useState as useState18, useCallback as useCallback17 } from "react";
2671
+ import { useState as useState19, useCallback as useCallback18 } from "react";
2646
2672
  function useArcadeGame(poolId, maxLives = 3) {
2647
2673
  const { client } = useDubs();
2648
2674
  const { user } = useAuth();
2649
- const [entry, setEntry] = useState18(null);
2650
- const [loading, setLoading] = useState18(false);
2651
- const [error, setError] = useState18(null);
2675
+ const [entry, setEntry] = useState19(null);
2676
+ const [loading, setLoading] = useState19(false);
2677
+ const [error, setError] = useState19(null);
2652
2678
  const walletAddress = user?.walletAddress || "";
2653
- const refreshEntry = useCallback17(async () => {
2679
+ const refreshEntry = useCallback18(async () => {
2654
2680
  if (!poolId || !walletAddress) return;
2655
2681
  setLoading(true);
2656
2682
  setError(null);
@@ -2667,7 +2693,7 @@ function useArcadeGame(poolId, maxLives = 3) {
2667
2693
  setLoading(false);
2668
2694
  }
2669
2695
  }, [client, poolId, walletAddress]);
2670
- const startAttempt = useCallback17(async () => {
2696
+ const startAttempt = useCallback18(async () => {
2671
2697
  if (!poolId || !walletAddress) throw new Error("Not ready");
2672
2698
  setError(null);
2673
2699
  try {
@@ -2679,7 +2705,7 @@ function useArcadeGame(poolId, maxLives = 3) {
2679
2705
  throw e;
2680
2706
  }
2681
2707
  }, [client, poolId, walletAddress]);
2682
- const submitScore = useCallback17(async (sessionToken, score, durationMs) => {
2708
+ const submitScore = useCallback18(async (sessionToken, score, durationMs) => {
2683
2709
  if (!poolId || !walletAddress) throw new Error("Not ready");
2684
2710
  setError(null);
2685
2711
  try {
@@ -2716,19 +2742,19 @@ function useArcadeGame(poolId, maxLives = 3) {
2716
2742
  }
2717
2743
 
2718
2744
  // src/hooks/useEnterArcadePool.ts
2719
- import { useState as useState19, useCallback as useCallback18 } from "react";
2745
+ import { useState as useState20, useCallback as useCallback19 } from "react";
2720
2746
  function useEnterArcadePool() {
2721
2747
  const { client, wallet, connection } = useDubs();
2722
2748
  const { user } = useAuth();
2723
- const [status, setStatus] = useState19("idle");
2724
- const [error, setError] = useState19(null);
2725
- const [data, setData] = useState19(null);
2726
- const reset = useCallback18(() => {
2749
+ const [status, setStatus] = useState20("idle");
2750
+ const [error, setError] = useState20(null);
2751
+ const [data, setData] = useState20(null);
2752
+ const reset = useCallback19(() => {
2727
2753
  setStatus("idle");
2728
2754
  setError(null);
2729
2755
  setData(null);
2730
2756
  }, []);
2731
- const execute = useCallback18(async (poolId) => {
2757
+ const execute = useCallback19(async (poolId) => {
2732
2758
  if (!wallet.publicKey) throw new Error("Wallet not connected");
2733
2759
  const walletAddress = wallet.publicKey.toBase58();
2734
2760
  setStatus("building");
@@ -2776,7 +2802,7 @@ function useEnterArcadePool() {
2776
2802
  }
2777
2803
 
2778
2804
  // src/hooks/useArcadeCountdown.ts
2779
- import { useState as useState20, useEffect as useEffect13, useRef as useRef4 } from "react";
2805
+ import { useState as useState21, useEffect as useEffect14, useRef as useRef4 } from "react";
2780
2806
  function formatCountdown(ms) {
2781
2807
  if (ms <= 0) return "Ended";
2782
2808
  const s2 = Math.floor(ms / 1e3);
@@ -2789,9 +2815,9 @@ function formatCountdown(ms) {
2789
2815
  return `${s2}s`;
2790
2816
  }
2791
2817
  function useArcadeCountdown(nextResolution) {
2792
- const [now, setNow] = useState20(Date.now());
2818
+ const [now, setNow] = useState21(Date.now());
2793
2819
  const intervalRef = useRef4(null);
2794
- useEffect13(() => {
2820
+ useEffect14(() => {
2795
2821
  if (!nextResolution) return;
2796
2822
  intervalRef.current = setInterval(() => setNow(Date.now()), 1e3);
2797
2823
  return () => {
@@ -2820,7 +2846,7 @@ function useArcadeCountdown(nextResolution) {
2820
2846
  }
2821
2847
 
2822
2848
  // src/hooks/useArcadeBridge.ts
2823
- import { useRef as useRef5, useState as useState21, useCallback as useCallback19 } from "react";
2849
+ import { useRef as useRef5, useState as useState22, useCallback as useCallback20 } from "react";
2824
2850
  var PROTOCOL_VERSION = "1.0";
2825
2851
  function useArcadeBridge({
2826
2852
  canPlay,
@@ -2835,9 +2861,9 @@ function useArcadeBridge({
2835
2861
  const gameStartTimeRef = useRef5(0);
2836
2862
  const canPlayRef = useRef5(canPlay);
2837
2863
  canPlayRef.current = canPlay;
2838
- const [lastResult, setLastResult] = useState21(null);
2839
- const [bridgeLoading, setBridgeLoading] = useState21(false);
2840
- const injectSession = useCallback19((token, attemptNumber) => {
2864
+ const [lastResult, setLastResult] = useState22(null);
2865
+ const [bridgeLoading, setBridgeLoading] = useState22(false);
2866
+ const injectSession = useCallback20((token, attemptNumber) => {
2841
2867
  webviewRef.current?.injectJavaScript(`
2842
2868
  window.ARCADE_SESSION_TOKEN = ${JSON.stringify(token)};
2843
2869
  window.ARCADE_ATTEMPT_NUMBER = ${attemptNumber};
@@ -2846,7 +2872,7 @@ function useArcadeBridge({
2846
2872
  true;
2847
2873
  `);
2848
2874
  }, []);
2849
- const triggerPlay = useCallback19(async () => {
2875
+ const triggerPlay = useCallback20(async () => {
2850
2876
  if (!canPlay) return;
2851
2877
  setBridgeLoading(true);
2852
2878
  try {
@@ -2863,7 +2889,7 @@ function useArcadeBridge({
2863
2889
  setBridgeLoading(false);
2864
2890
  }
2865
2891
  }, [canPlay, startAttempt, injectSession, onPlayStarted, onError]);
2866
- const handleMessage = useCallback19(
2892
+ const handleMessage = useCallback20(
2867
2893
  async (event) => {
2868
2894
  let data;
2869
2895
  try {
@@ -3076,11 +3102,11 @@ function AuthGate({
3076
3102
  }) {
3077
3103
  const { client, pushEnabled } = useDubs();
3078
3104
  const auth = useAuth();
3079
- const [phase, setPhase] = useState22("init");
3080
- const [registrationPhase, setRegistrationPhase] = useState22(false);
3081
- const [showPushSetup, setShowPushSetup] = useState22(false);
3082
- const [isRestoredSession, setIsRestoredSession] = useState22(false);
3083
- useEffect14(() => {
3105
+ const [phase, setPhase] = useState23("init");
3106
+ const [registrationPhase, setRegistrationPhase] = useState23(false);
3107
+ const [showPushSetup, setShowPushSetup] = useState23(false);
3108
+ const [isRestoredSession, setIsRestoredSession] = useState23(false);
3109
+ useEffect15(() => {
3084
3110
  let cancelled = false;
3085
3111
  (async () => {
3086
3112
  try {
@@ -3107,23 +3133,23 @@ function AuthGate({
3107
3133
  cancelled = true;
3108
3134
  };
3109
3135
  }, []);
3110
- useEffect14(() => {
3136
+ useEffect15(() => {
3111
3137
  if (auth.status === "needsRegistration") setRegistrationPhase(true);
3112
3138
  }, [auth.status]);
3113
- useEffect14(() => {
3139
+ useEffect15(() => {
3114
3140
  if (pushEnabled && auth.status === "authenticated" && registrationPhase && !isRestoredSession) {
3115
3141
  setShowPushSetup(true);
3116
3142
  }
3117
3143
  }, [pushEnabled, auth.status, registrationPhase, isRestoredSession]);
3118
- useEffect14(() => {
3144
+ useEffect15(() => {
3119
3145
  if (auth.token) onSaveToken(auth.token);
3120
3146
  }, [auth.token]);
3121
- const retry = useCallback20(() => {
3147
+ const retry = useCallback21(() => {
3122
3148
  setRegistrationPhase(false);
3123
3149
  auth.reset();
3124
3150
  auth.authenticate();
3125
3151
  }, [auth]);
3126
- const handleRegister = useCallback20(
3152
+ const handleRegister = useCallback21(
3127
3153
  (username, referralCode, avatarUrl) => {
3128
3154
  auth.register(username, referralCode, avatarUrl);
3129
3155
  },
@@ -3247,20 +3273,20 @@ function DefaultRegistrationScreen({
3247
3273
  }) {
3248
3274
  const t = useDubsTheme();
3249
3275
  const accent = accentColor || t.accent;
3250
- const [step, setStep] = useState22(0);
3251
- const [avatarSeed, setAvatarSeed] = useState22(generateSeed);
3252
- const [avatarStyle, setAvatarStyle] = useState22("adventurer");
3253
- const [avatarBg, setAvatarBg] = useState22("1a1a2e");
3254
- const [showStyles, setShowStyles] = useState22(false);
3255
- const [username, setUsername] = useState22("");
3256
- const [referralCode, setReferralCode] = useState22("");
3257
- const [checking, setChecking] = useState22(false);
3258
- const [availability, setAvailability] = useState22(null);
3276
+ const [step, setStep] = useState23(0);
3277
+ const [avatarSeed, setAvatarSeed] = useState23(generateSeed);
3278
+ const [avatarStyle, setAvatarStyle] = useState23("adventurer");
3279
+ const [avatarBg, setAvatarBg] = useState23("1a1a2e");
3280
+ const [showStyles, setShowStyles] = useState23(false);
3281
+ const [username, setUsername] = useState23("");
3282
+ const [referralCode, setReferralCode] = useState23("");
3283
+ const [checking, setChecking] = useState23(false);
3284
+ const [availability, setAvailability] = useState23(null);
3259
3285
  const debounceRef = useRef6(null);
3260
3286
  const fadeAnim = useRef6(new Animated.Value(1)).current;
3261
3287
  const slideAnim = useRef6(new Animated.Value(0)).current;
3262
3288
  const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);
3263
- useEffect14(() => {
3289
+ useEffect15(() => {
3264
3290
  if (debounceRef.current) clearTimeout(debounceRef.current);
3265
3291
  const trimmed = username.trim();
3266
3292
  if (trimmed.length < 3) {
@@ -3283,7 +3309,7 @@ function DefaultRegistrationScreen({
3283
3309
  if (debounceRef.current) clearTimeout(debounceRef.current);
3284
3310
  };
3285
3311
  }, [username, client]);
3286
- const animateToStep = useCallback20((newStep) => {
3312
+ const animateToStep = useCallback21((newStep) => {
3287
3313
  const dir = newStep > step ? 1 : -1;
3288
3314
  Keyboard.dismiss();
3289
3315
  Animated.parallel([
@@ -3523,7 +3549,7 @@ function DefaultRegistrationScreen({
3523
3549
  function PushTokenRestorer() {
3524
3550
  const push = usePushNotifications();
3525
3551
  const restored = useRef6(false);
3526
- useEffect14(() => {
3552
+ useEffect15(() => {
3527
3553
  if (restored.current) return;
3528
3554
  restored.current = true;
3529
3555
  push.restoreIfGranted();
@@ -3540,7 +3566,7 @@ function PushSetupScreen({
3540
3566
  const push = usePushNotifications();
3541
3567
  const fadeAnim = useRef6(new Animated.Value(0)).current;
3542
3568
  const slideAnim = useRef6(new Animated.Value(30)).current;
3543
- useEffect14(() => {
3569
+ useEffect15(() => {
3544
3570
  Animated.parallel([
3545
3571
  Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }),
3546
3572
  Animated.timing(slideAnim, { toValue: 0, duration: 300, useNativeDriver: true })
@@ -3700,9 +3726,9 @@ function DubsProvider({
3700
3726
  const rpcUrl = rpcUrlOverride || config.rpcUrl;
3701
3727
  const client = useMemo3(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
3702
3728
  const storage = useMemo3(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
3703
- const [uiConfig, setUiConfig] = useState23(null);
3704
- const [resolvedNetwork, setResolvedNetwork] = useState23(network);
3705
- useEffect15(() => {
3729
+ const [uiConfig, setUiConfig] = useState24(null);
3730
+ const [resolvedNetwork, setResolvedNetwork] = useState24(network);
3731
+ useEffect16(() => {
3706
3732
  client.getAppConfig().then((cfg) => {
3707
3733
  console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
3708
3734
  setUiConfig(cfg);
@@ -3794,7 +3820,7 @@ function ManagedInner({
3794
3820
  children
3795
3821
  }) {
3796
3822
  const managedDisconnect = useDisconnect();
3797
- const disconnect = useCallback21(async () => {
3823
+ const disconnect = useCallback22(async () => {
3798
3824
  client.setToken(null);
3799
3825
  await managedDisconnect?.();
3800
3826
  }, [client, managedDisconnect]);
@@ -3835,7 +3861,7 @@ function ExternalWalletProvider({
3835
3861
  pushEnabled,
3836
3862
  children
3837
3863
  }) {
3838
- const disconnect = useCallback21(async () => {
3864
+ const disconnect = useCallback22(async () => {
3839
3865
  client.setToken(null);
3840
3866
  await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
3841
3867
  });
@@ -4156,7 +4182,7 @@ var styles5 = StyleSheet6.create({
4156
4182
  });
4157
4183
 
4158
4184
  // src/ui/UserProfileSheet.tsx
4159
- import { useState as useState24, useEffect as useEffect16, useRef as useRef7, useCallback as useCallback22, useMemo as useMemo5 } from "react";
4185
+ import { useState as useState25, useEffect as useEffect17, useRef as useRef7, useCallback as useCallback23, useMemo as useMemo5 } from "react";
4160
4186
  import {
4161
4187
  View as View7,
4162
4188
  Text as Text7,
@@ -4189,29 +4215,29 @@ function UserProfileSheet({
4189
4215
  const push = usePushNotifications();
4190
4216
  const overlayOpacity = useRef7(new Animated2.Value(0)).current;
4191
4217
  const parsed = useMemo5(() => parseAvatarUrl(user.avatar), [user.avatar]);
4192
- const [avatarStyle, setAvatarStyle] = useState24(parsed.style);
4193
- const [avatarSeed, setAvatarSeed] = useState24(parsed.seed);
4194
- const [bgColor, setBgColor] = useState24(parsed.bg);
4195
- const [saving, setSaving] = useState24(false);
4196
- const [error, setError] = useState24(null);
4197
- useEffect16(() => {
4218
+ const [avatarStyle, setAvatarStyle] = useState25(parsed.style);
4219
+ const [avatarSeed, setAvatarSeed] = useState25(parsed.seed);
4220
+ const [bgColor, setBgColor] = useState25(parsed.bg);
4221
+ const [saving, setSaving] = useState25(false);
4222
+ const [error, setError] = useState25(null);
4223
+ useEffect17(() => {
4198
4224
  const p = parseAvatarUrl(user.avatar);
4199
4225
  setAvatarStyle(p.style);
4200
4226
  setAvatarSeed(p.seed);
4201
4227
  setBgColor(p.bg);
4202
4228
  }, [user.avatar]);
4203
- useEffect16(() => {
4229
+ useEffect17(() => {
4204
4230
  Animated2.timing(overlayOpacity, {
4205
4231
  toValue: visible ? 1 : 0,
4206
4232
  duration: 250,
4207
4233
  useNativeDriver: true
4208
4234
  }).start();
4209
4235
  }, [visible, overlayOpacity]);
4210
- useEffect16(() => {
4236
+ useEffect17(() => {
4211
4237
  if (visible) setError(null);
4212
4238
  }, [visible]);
4213
4239
  const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
4214
- const saveAvatar = useCallback22(async (newUrl) => {
4240
+ const saveAvatar = useCallback23(async (newUrl) => {
4215
4241
  setSaving(true);
4216
4242
  setError(null);
4217
4243
  try {
@@ -4224,16 +4250,16 @@ function UserProfileSheet({
4224
4250
  setSaving(false);
4225
4251
  }
4226
4252
  }, [client, refreshUser, onAvatarUpdated]);
4227
- const handleStyleChange = useCallback22((style) => {
4253
+ const handleStyleChange = useCallback23((style) => {
4228
4254
  setAvatarStyle(style);
4229
4255
  saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
4230
4256
  }, [avatarSeed, bgColor, saveAvatar]);
4231
- const handleShuffle = useCallback22(() => {
4257
+ const handleShuffle = useCallback23(() => {
4232
4258
  const newSeed = generateSeed();
4233
4259
  setAvatarSeed(newSeed);
4234
4260
  saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
4235
4261
  }, [avatarStyle, bgColor, saveAvatar]);
4236
- const handleBgChange = useCallback22((color) => {
4262
+ const handleBgChange = useCallback23((color) => {
4237
4263
  setBgColor(color);
4238
4264
  saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
4239
4265
  }, [avatarStyle, avatarSeed, saveAvatar]);
@@ -4513,7 +4539,7 @@ var styles6 = StyleSheet7.create({
4513
4539
  });
4514
4540
 
4515
4541
  // src/ui/game/GamePoster.tsx
4516
- import { useState as useState25 } from "react";
4542
+ import { useState as useState26 } from "react";
4517
4543
  import { StyleSheet as StyleSheet8, View as View8, Text as Text8 } from "react-native";
4518
4544
  import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
4519
4545
  function computeCountdown(lockTimestamp) {
@@ -4563,7 +4589,7 @@ function GamePoster({ game, ImageComponent }) {
4563
4589
  ] });
4564
4590
  }
4565
4591
  function TeamLogoInternal({ url, size, Img }) {
4566
- const [failed, setFailed] = useState25(false);
4592
+ const [failed, setFailed] = useState26(false);
4567
4593
  if (!url || failed) {
4568
4594
  return /* @__PURE__ */ jsx10(View8, { style: [styles7.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
4569
4595
  }
@@ -4743,7 +4769,7 @@ var styles8 = StyleSheet9.create({
4743
4769
  });
4744
4770
 
4745
4771
  // src/ui/game/PickWinnerCard.tsx
4746
- import { useState as useState26, useMemo as useMemo7 } from "react";
4772
+ import { useState as useState27, useMemo as useMemo7 } from "react";
4747
4773
  import { StyleSheet as StyleSheet10, View as View10, Text as Text10, TouchableOpacity as TouchableOpacity7 } from "react-native";
4748
4774
  import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
4749
4775
  function PickWinnerCard({
@@ -4814,7 +4840,7 @@ function TeamOption({
4814
4840
  ImageComponent,
4815
4841
  t
4816
4842
  }) {
4817
- const [imgFailed, setImgFailed] = useState26(false);
4843
+ const [imgFailed, setImgFailed] = useState27(false);
4818
4844
  const Img = ImageComponent || __require("react-native").Image;
4819
4845
  const showImage = imageUrl && !imgFailed;
4820
4846
  return /* @__PURE__ */ jsxs9(
@@ -4855,7 +4881,7 @@ var styles9 = StyleSheet10.create({
4855
4881
  });
4856
4882
 
4857
4883
  // src/ui/game/PlayersCard.tsx
4858
- import { useState as useState27 } from "react";
4884
+ import { useState as useState28 } from "react";
4859
4885
  import { StyleSheet as StyleSheet11, View as View11, Text as Text11 } from "react-native";
4860
4886
  import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
4861
4887
  function truncateWallet(addr, chars) {
@@ -4904,7 +4930,7 @@ function BettorRow({
4904
4930
  ImageComponent,
4905
4931
  t
4906
4932
  }) {
4907
- const [imgFailed, setImgFailed] = useState27(false);
4933
+ const [imgFailed, setImgFailed] = useState28(false);
4908
4934
  const Img = ImageComponent || __require("react-native").Image;
4909
4935
  const showAvatar = bettor.avatar && !imgFailed;
4910
4936
  return /* @__PURE__ */ jsxs10(View11, { style: [styles10.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
@@ -4983,7 +5009,7 @@ var styles11 = StyleSheet12.create({
4983
5009
  });
4984
5010
 
4985
5011
  // src/ui/game/CreateCustomGameSheet.tsx
4986
- import { useState as useState28, useEffect as useEffect17, useRef as useRef8, useCallback as useCallback23 } from "react";
5012
+ import { useState as useState29, useEffect as useEffect18, useRef as useRef8, useCallback as useCallback24 } from "react";
4987
5013
  import {
4988
5014
  View as View13,
4989
5015
  Text as Text13,
@@ -5020,18 +5046,18 @@ function CreateCustomGameSheet({
5020
5046
  const t = useDubsTheme();
5021
5047
  const { wallet } = useDubs();
5022
5048
  const mutation = useCreateCustomGame();
5023
- const [selectedAmount, setSelectedAmount] = useState28(null);
5024
- const [customAmount, setCustomAmount] = useState28("");
5025
- const [isCustom, setIsCustom] = useState28(false);
5049
+ const [selectedAmount, setSelectedAmount] = useState29(null);
5050
+ const [customAmount, setCustomAmount] = useState29("");
5051
+ const [isCustom, setIsCustom] = useState29(false);
5026
5052
  const overlayOpacity = useRef8(new Animated3.Value(0)).current;
5027
- useEffect17(() => {
5053
+ useEffect18(() => {
5028
5054
  Animated3.timing(overlayOpacity, {
5029
5055
  toValue: visible ? 1 : 0,
5030
5056
  duration: 250,
5031
5057
  useNativeDriver: true
5032
5058
  }).start();
5033
5059
  }, [visible, overlayOpacity]);
5034
- useEffect17(() => {
5060
+ useEffect18(() => {
5035
5061
  if (visible) {
5036
5062
  setSelectedAmount(defaultAmount ?? null);
5037
5063
  setCustomAmount("");
@@ -5039,7 +5065,7 @@ function CreateCustomGameSheet({
5039
5065
  mutation.reset();
5040
5066
  }
5041
5067
  }, [visible]);
5042
- useEffect17(() => {
5068
+ useEffect18(() => {
5043
5069
  if (mutation.status === "success" && mutation.data) {
5044
5070
  onSuccess?.(mutation.data);
5045
5071
  const timer = setTimeout(() => {
@@ -5048,23 +5074,23 @@ function CreateCustomGameSheet({
5048
5074
  return () => clearTimeout(timer);
5049
5075
  }
5050
5076
  }, [mutation.status, mutation.data]);
5051
- useEffect17(() => {
5077
+ useEffect18(() => {
5052
5078
  if (mutation.status === "error" && mutation.error) {
5053
5079
  onError?.(mutation.error);
5054
5080
  }
5055
5081
  }, [mutation.status, mutation.error]);
5056
- const handlePresetSelect = useCallback23((amount) => {
5082
+ const handlePresetSelect = useCallback24((amount) => {
5057
5083
  setSelectedAmount(amount);
5058
5084
  setIsCustom(false);
5059
5085
  setCustomAmount("");
5060
5086
  onAmountChange?.(amount);
5061
5087
  }, [onAmountChange]);
5062
- const handleCustomSelect = useCallback23(() => {
5088
+ const handleCustomSelect = useCallback24(() => {
5063
5089
  setIsCustom(true);
5064
5090
  setSelectedAmount(null);
5065
5091
  onAmountChange?.(null);
5066
5092
  }, [onAmountChange]);
5067
- const handleCustomAmountChange = useCallback23((text) => {
5093
+ const handleCustomAmountChange = useCallback24((text) => {
5068
5094
  const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
5069
5095
  setCustomAmount(cleaned);
5070
5096
  const parsed = parseFloat(cleaned);
@@ -5079,7 +5105,7 @@ function CreateCustomGameSheet({
5079
5105
  const winnerTakes = pot * (1 - fee / 100);
5080
5106
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5081
5107
  const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
5082
- const handleCreate = useCallback23(async () => {
5108
+ const handleCreate = useCallback24(async () => {
5083
5109
  if (!finalAmount || !wallet.publicKey) return;
5084
5110
  try {
5085
5111
  await mutation.execute({
@@ -5348,7 +5374,7 @@ var styles12 = StyleSheet13.create({
5348
5374
  });
5349
5375
 
5350
5376
  // src/ui/game/JoinGameSheet.tsx
5351
- import { useState as useState30, useEffect as useEffect18, useRef as useRef10, useCallback as useCallback25, useMemo as useMemo9 } from "react";
5377
+ import { useState as useState31, useEffect as useEffect19, useRef as useRef10, useCallback as useCallback26, useMemo as useMemo9 } from "react";
5352
5378
  import {
5353
5379
  View as View16,
5354
5380
  Text as Text16,
@@ -5558,7 +5584,7 @@ var styles13 = StyleSheet14.create({
5558
5584
  });
5559
5585
 
5560
5586
  // src/ui/game/TeamButton.tsx
5561
- import { useState as useState29 } from "react";
5587
+ import { useState as useState30 } from "react";
5562
5588
  import { View as View15, Text as Text15, TouchableOpacity as TouchableOpacity10, StyleSheet as StyleSheet15 } from "react-native";
5563
5589
  import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
5564
5590
  function TeamButton({
@@ -5572,7 +5598,7 @@ function TeamButton({
5572
5598
  ImageComponent,
5573
5599
  t
5574
5600
  }) {
5575
- const [imgFailed, setImgFailed] = useState29(false);
5601
+ const [imgFailed, setImgFailed] = useState30(false);
5576
5602
  const Img = ImageComponent || __require("react-native").Image;
5577
5603
  const showImage = imageUrl && !imgFailed;
5578
5604
  return /* @__PURE__ */ jsxs14(
@@ -5676,20 +5702,20 @@ function JoinGameSheet({
5676
5702
  const { wallet } = useDubs();
5677
5703
  const mutation = useJoinGame();
5678
5704
  const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
5679
- const [selectedTeam, setSelectedTeam] = useState30(null);
5680
- const [wager, setWager] = useState30(game.buyIn);
5681
- const [showSuccess, setShowSuccess] = useState30(false);
5705
+ const [selectedTeam, setSelectedTeam] = useState31(null);
5706
+ const [wager, setWager] = useState31(game.buyIn);
5707
+ const [showSuccess, setShowSuccess] = useState31(false);
5682
5708
  const overlayOpacity = useRef10(new Animated4.Value(0)).current;
5683
5709
  const successScale = useRef10(new Animated4.Value(0)).current;
5684
5710
  const successOpacity = useRef10(new Animated4.Value(0)).current;
5685
- useEffect18(() => {
5711
+ useEffect19(() => {
5686
5712
  Animated4.timing(overlayOpacity, {
5687
5713
  toValue: visible ? 1 : 0,
5688
5714
  duration: 250,
5689
5715
  useNativeDriver: true
5690
5716
  }).start();
5691
5717
  }, [visible, overlayOpacity]);
5692
- useEffect18(() => {
5718
+ useEffect19(() => {
5693
5719
  if (visible) {
5694
5720
  setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
5695
5721
  setWager(game.buyIn);
@@ -5699,7 +5725,7 @@ function JoinGameSheet({
5699
5725
  mutation.reset();
5700
5726
  }
5701
5727
  }, [visible]);
5702
- useEffect18(() => {
5728
+ useEffect19(() => {
5703
5729
  if (mutation.status === "success" && mutation.data) {
5704
5730
  setShowSuccess(true);
5705
5731
  onSuccess?.(mutation.data);
@@ -5716,7 +5742,7 @@ function JoinGameSheet({
5716
5742
  return () => clearTimeout(timer);
5717
5743
  }
5718
5744
  }, [mutation.status, mutation.data]);
5719
- useEffect18(() => {
5745
+ useEffect19(() => {
5720
5746
  if (mutation.status === "error" && mutation.error) {
5721
5747
  onError?.(mutation.error);
5722
5748
  }
@@ -5760,7 +5786,7 @@ function JoinGameSheet({
5760
5786
  const alreadyJoined = myBet !== null;
5761
5787
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
5762
5788
  const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
5763
- const handleJoin = useCallback25(async () => {
5789
+ const handleJoin = useCallback26(async () => {
5764
5790
  if (!selectedTeam || !wallet.publicKey) return;
5765
5791
  try {
5766
5792
  await mutation.execute({
@@ -5820,13 +5846,15 @@ function JoinGameSheet({
5820
5846
  ] }) })
5821
5847
  ] })
5822
5848
  ] }),
5823
- !isCustomGame && !isPoolModeEnabled && !alreadyJoined && /* @__PURE__ */ jsxs15(View16, { style: styles15.section, children: [
5824
- /* @__PURE__ */ jsx18(Text16, { style: [styles15.sectionLabel, { color: t.textSecondary }], children: "Pick Your Side" }),
5825
- /* @__PURE__ */ jsxs15(View16, { style: styles15.teamsRow, children: [
5849
+ !isCustomGame && !isPoolModeEnabled && !alreadyJoined && (hasDrawOption ? (
5850
+ /* ── 3-way layout: Home / VS / Away / OR / Draw ── */
5851
+ /* @__PURE__ */ jsxs15(View16, { style: styles15.section, children: [
5852
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.sectionLabel, { color: t.textSecondary }], children: "Who will win?" }),
5826
5853
  /* @__PURE__ */ jsx18(
5827
- TeamButton,
5854
+ PickRow,
5828
5855
  {
5829
5856
  name: homeName,
5857
+ subtitle: "Home Team",
5830
5858
  imageUrl: opponents[0]?.imageUrl,
5831
5859
  odds: homeOdds,
5832
5860
  bets: homeBets,
@@ -5840,10 +5868,16 @@ function JoinGameSheet({
5840
5868
  t
5841
5869
  }
5842
5870
  ),
5871
+ /* @__PURE__ */ jsxs15(View16, { style: styles15.dividerRow, children: [
5872
+ /* @__PURE__ */ jsx18(View16, { style: [styles15.dividerLine, { backgroundColor: t.border }] }),
5873
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.dividerText, { color: t.textMuted }], children: "VS" }),
5874
+ /* @__PURE__ */ jsx18(View16, { style: [styles15.dividerLine, { backgroundColor: t.border }] })
5875
+ ] }),
5843
5876
  /* @__PURE__ */ jsx18(
5844
- TeamButton,
5877
+ PickRow,
5845
5878
  {
5846
5879
  name: awayName,
5880
+ subtitle: "Away Team",
5847
5881
  imageUrl: opponents[1]?.imageUrl,
5848
5882
  odds: awayOdds,
5849
5883
  bets: awayBets,
@@ -5856,24 +5890,71 @@ function JoinGameSheet({
5856
5890
  ImageComponent,
5857
5891
  t
5858
5892
  }
5893
+ ),
5894
+ /* @__PURE__ */ jsxs15(View16, { style: styles15.dividerRow, children: [
5895
+ /* @__PURE__ */ jsx18(View16, { style: [styles15.dividerLine, { backgroundColor: t.border }] }),
5896
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.dividerText, { color: t.textMuted }], children: "OR" }),
5897
+ /* @__PURE__ */ jsx18(View16, { style: [styles15.dividerLine, { backgroundColor: t.border }] })
5898
+ ] }),
5899
+ /* @__PURE__ */ jsx18(
5900
+ PickRow,
5901
+ {
5902
+ name: "Draw",
5903
+ subtitle: "Match ends in a tie",
5904
+ odds: drawOdds,
5905
+ bets: drawBets,
5906
+ color: drawColor,
5907
+ selected: selectedTeam === "draw",
5908
+ onPress: () => {
5909
+ setSelectedTeam("draw");
5910
+ onTeamSelect?.("draw");
5911
+ },
5912
+ t
5913
+ }
5859
5914
  )
5860
- ] }),
5861
- hasDrawOption && /* @__PURE__ */ jsx18(View16, { style: styles15.drawRow, children: /* @__PURE__ */ jsx18(
5862
- TeamButton,
5863
- {
5864
- name: "Draw",
5865
- odds: drawOdds,
5866
- bets: drawBets,
5867
- color: drawColor,
5868
- selected: selectedTeam === "draw",
5869
- onPress: () => {
5870
- setSelectedTeam("draw");
5871
- onTeamSelect?.("draw");
5872
- },
5873
- t
5874
- }
5875
- ) })
5876
- ] }),
5915
+ ] })
5916
+ ) : (
5917
+ /* ── 2-way layout: side by side ── */
5918
+ /* @__PURE__ */ jsxs15(View16, { style: styles15.section, children: [
5919
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.sectionLabel, { color: t.textSecondary }], children: "Pick Your Side" }),
5920
+ /* @__PURE__ */ jsxs15(View16, { style: styles15.teamsRow, children: [
5921
+ /* @__PURE__ */ jsx18(
5922
+ TeamButton,
5923
+ {
5924
+ name: homeName,
5925
+ imageUrl: opponents[0]?.imageUrl,
5926
+ odds: homeOdds,
5927
+ bets: homeBets,
5928
+ color: homeColor,
5929
+ selected: selectedTeam === "home",
5930
+ onPress: () => {
5931
+ setSelectedTeam("home");
5932
+ onTeamSelect?.("home");
5933
+ },
5934
+ ImageComponent,
5935
+ t
5936
+ }
5937
+ ),
5938
+ /* @__PURE__ */ jsx18(
5939
+ TeamButton,
5940
+ {
5941
+ name: awayName,
5942
+ imageUrl: opponents[1]?.imageUrl,
5943
+ odds: awayOdds,
5944
+ bets: awayBets,
5945
+ color: awayColor,
5946
+ selected: selectedTeam === "away",
5947
+ onPress: () => {
5948
+ setSelectedTeam("away");
5949
+ onTeamSelect?.("away");
5950
+ },
5951
+ ImageComponent,
5952
+ t
5953
+ }
5954
+ )
5955
+ ] })
5956
+ ] })
5957
+ )),
5877
5958
  alreadyJoined && myBet && /* @__PURE__ */ jsxs15(View16, { style: [styles15.myBetCard, { backgroundColor: (myBet.team === "home" ? homeColor : myBet.team === "away" ? awayColor : drawColor) + "15", borderColor: myBet.team === "home" ? homeColor : myBet.team === "away" ? awayColor : drawColor }], children: [
5878
5959
  /* @__PURE__ */ jsx18(Text16, { style: [styles15.myBetLabel, { color: myBet.team === "home" ? homeColor : myBet.team === "away" ? awayColor : drawColor }], children: "YOUR BET" }),
5879
5960
  /* @__PURE__ */ jsx18(Text16, { style: [styles15.myBetTeam, { color: t.text }], children: myBet.team === "home" ? homeName : myBet.team === "away" ? awayName : "Draw" }),
@@ -5956,6 +6037,100 @@ function JoinGameSheet({
5956
6037
  }
5957
6038
  );
5958
6039
  }
6040
+ function PickRow({
6041
+ name,
6042
+ subtitle,
6043
+ imageUrl,
6044
+ odds,
6045
+ bets,
6046
+ color,
6047
+ selected,
6048
+ onPress,
6049
+ ImageComponent,
6050
+ t
6051
+ }) {
6052
+ const [imgFailed, setImgFailed] = useState31(false);
6053
+ const Img = ImageComponent || __require("react-native").Image;
6054
+ const showImage = imageUrl && !imgFailed;
6055
+ return /* @__PURE__ */ jsxs15(
6056
+ TouchableOpacity11,
6057
+ {
6058
+ style: [pickStyles.row, { borderColor: selected ? color : t.border, backgroundColor: selected ? color + "12" : t.background }],
6059
+ onPress,
6060
+ activeOpacity: 0.7,
6061
+ children: [
6062
+ showImage ? /* @__PURE__ */ jsx18(Img, { source: { uri: imageUrl }, style: pickStyles.logo, resizeMode: "contain", onError: () => setImgFailed(true) }) : /* @__PURE__ */ jsx18(View16, { style: [pickStyles.logoPlaceholder, { backgroundColor: color + "20" }], children: /* @__PURE__ */ jsx18(Text16, { style: [pickStyles.logoEmoji, { color }], children: name === "Draw" ? "\u{1F91D}" : name.charAt(0) }) }),
6063
+ /* @__PURE__ */ jsxs15(View16, { style: pickStyles.info, children: [
6064
+ /* @__PURE__ */ jsx18(Text16, { style: [pickStyles.name, { color: t.text }], children: name }),
6065
+ subtitle && /* @__PURE__ */ jsx18(Text16, { style: [pickStyles.subtitle, { color: t.textMuted }], children: subtitle })
6066
+ ] }),
6067
+ odds !== "\u2014" && /* @__PURE__ */ jsxs15(Text16, { style: [pickStyles.odds, { color }], children: [
6068
+ odds,
6069
+ "x"
6070
+ ] }),
6071
+ bets > 0 && /* @__PURE__ */ jsx18(Text16, { style: [pickStyles.bets, { color: t.textMuted }], children: bets }),
6072
+ selected && /* @__PURE__ */ jsx18(View16, { style: [pickStyles.check, { backgroundColor: color }], children: /* @__PURE__ */ jsx18(Text16, { style: pickStyles.checkText, children: "\u2713" }) })
6073
+ ]
6074
+ }
6075
+ );
6076
+ }
6077
+ var pickStyles = StyleSheet16.create({
6078
+ row: {
6079
+ flexDirection: "row",
6080
+ alignItems: "center",
6081
+ borderWidth: 1.5,
6082
+ borderRadius: 14,
6083
+ paddingVertical: 12,
6084
+ paddingHorizontal: 14,
6085
+ gap: 12
6086
+ },
6087
+ logo: {
6088
+ width: 36,
6089
+ height: 36,
6090
+ borderRadius: 18
6091
+ },
6092
+ logoPlaceholder: {
6093
+ width: 36,
6094
+ height: 36,
6095
+ borderRadius: 18,
6096
+ alignItems: "center",
6097
+ justifyContent: "center"
6098
+ },
6099
+ logoEmoji: {
6100
+ fontSize: 16,
6101
+ fontWeight: "800"
6102
+ },
6103
+ info: {
6104
+ flex: 1
6105
+ },
6106
+ name: {
6107
+ fontSize: 15,
6108
+ fontWeight: "700"
6109
+ },
6110
+ subtitle: {
6111
+ fontSize: 12,
6112
+ marginTop: 1
6113
+ },
6114
+ odds: {
6115
+ fontSize: 16,
6116
+ fontWeight: "800"
6117
+ },
6118
+ bets: {
6119
+ fontSize: 12
6120
+ },
6121
+ check: {
6122
+ width: 22,
6123
+ height: 22,
6124
+ borderRadius: 11,
6125
+ alignItems: "center",
6126
+ justifyContent: "center"
6127
+ },
6128
+ checkText: {
6129
+ color: "#FFF",
6130
+ fontSize: 13,
6131
+ fontWeight: "800"
6132
+ }
6133
+ });
5959
6134
  var styles15 = StyleSheet16.create({
5960
6135
  overlay: {
5961
6136
  ...StyleSheet16.absoluteFillObject,
@@ -6078,6 +6253,20 @@ var styles15 = StyleSheet16.create({
6078
6253
  drawRow: {
6079
6254
  marginTop: 8
6080
6255
  },
6256
+ dividerRow: {
6257
+ flexDirection: "row",
6258
+ alignItems: "center",
6259
+ gap: 12,
6260
+ marginVertical: 6
6261
+ },
6262
+ dividerLine: {
6263
+ flex: 1,
6264
+ height: 1
6265
+ },
6266
+ dividerText: {
6267
+ fontSize: 12,
6268
+ fontWeight: "700"
6269
+ },
6081
6270
  summaryCard: {
6082
6271
  marginTop: 20,
6083
6272
  borderRadius: 16,
@@ -6153,7 +6342,7 @@ var styles15 = StyleSheet16.create({
6153
6342
  });
6154
6343
 
6155
6344
  // src/ui/game/ClaimPrizeSheet.tsx
6156
- import { useState as useState31, useEffect as useEffect19, useRef as useRef11, useCallback as useCallback26 } from "react";
6345
+ import { useState as useState32, useEffect as useEffect20, useRef as useRef11, useCallback as useCallback27 } from "react";
6157
6346
  import {
6158
6347
  View as View17,
6159
6348
  Text as Text17,
@@ -6187,15 +6376,15 @@ function ClaimPrizeSheet({
6187
6376
  const overlayOpacity = useRef11(new Animated5.Value(0)).current;
6188
6377
  const celebrationScale = useRef11(new Animated5.Value(0)).current;
6189
6378
  const celebrationOpacity = useRef11(new Animated5.Value(0)).current;
6190
- const [showCelebration, setShowCelebration] = useState31(false);
6191
- useEffect19(() => {
6379
+ const [showCelebration, setShowCelebration] = useState32(false);
6380
+ useEffect20(() => {
6192
6381
  Animated5.timing(overlayOpacity, {
6193
6382
  toValue: visible ? 1 : 0,
6194
6383
  duration: 250,
6195
6384
  useNativeDriver: true
6196
6385
  }).start();
6197
6386
  }, [visible, overlayOpacity]);
6198
- useEffect19(() => {
6387
+ useEffect20(() => {
6199
6388
  if (visible) {
6200
6389
  mutation.reset();
6201
6390
  setShowCelebration(false);
@@ -6203,7 +6392,7 @@ function ClaimPrizeSheet({
6203
6392
  celebrationOpacity.setValue(0);
6204
6393
  }
6205
6394
  }, [visible]);
6206
- useEffect19(() => {
6395
+ useEffect20(() => {
6207
6396
  if (mutation.status === "success" && mutation.data) {
6208
6397
  setShowCelebration(true);
6209
6398
  Animated5.parallel([
@@ -6226,14 +6415,14 @@ function ClaimPrizeSheet({
6226
6415
  return () => clearTimeout(timer);
6227
6416
  }
6228
6417
  }, [mutation.status, mutation.data]);
6229
- useEffect19(() => {
6418
+ useEffect20(() => {
6230
6419
  if (mutation.status === "error" && mutation.error) {
6231
6420
  onError?.(mutation.error);
6232
6421
  }
6233
6422
  }, [mutation.status, mutation.error]);
6234
6423
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
6235
6424
  const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
6236
- const handleClaim = useCallback26(async () => {
6425
+ const handleClaim = useCallback27(async () => {
6237
6426
  if (!wallet.publicKey) return;
6238
6427
  try {
6239
6428
  await mutation.execute({
@@ -6466,7 +6655,7 @@ var styles16 = StyleSheet17.create({
6466
6655
  });
6467
6656
 
6468
6657
  // src/ui/game/ClaimButton.tsx
6469
- import { useState as useState32, useMemo as useMemo10, useCallback as useCallback27 } from "react";
6658
+ import { useState as useState33, useMemo as useMemo10, useCallback as useCallback28 } from "react";
6470
6659
  import { StyleSheet as StyleSheet18, Text as Text18, TouchableOpacity as TouchableOpacity13 } from "react-native";
6471
6660
  import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
6472
6661
  function ClaimButton({ gameId, style, onSuccess, onError }) {
@@ -6474,7 +6663,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
6474
6663
  const { wallet } = useDubs();
6475
6664
  const game = useGame(gameId);
6476
6665
  const claimStatus = useHasClaimed(gameId);
6477
- const [sheetVisible, setSheetVisible] = useState32(false);
6666
+ const [sheetVisible, setSheetVisible] = useState33(false);
6478
6667
  const walletAddress = wallet.publicKey?.toBase58() ?? null;
6479
6668
  const myBet = useMemo10(() => {
6480
6669
  if (!walletAddress || !game.data?.bettors) return null;
@@ -6485,7 +6674,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
6485
6674
  const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
6486
6675
  const isEligible = myBet != null && isResolved && (isWinner || isRefund);
6487
6676
  const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
6488
- const handleSuccess = useCallback27(
6677
+ const handleSuccess = useCallback28(
6489
6678
  (result) => {
6490
6679
  claimStatus.refetch();
6491
6680
  onSuccess?.(result);
@@ -6572,7 +6761,7 @@ var styles17 = StyleSheet18.create({
6572
6761
  });
6573
6762
 
6574
6763
  // src/ui/game/EnterArcadePoolSheet.tsx
6575
- import { useEffect as useEffect20, useRef as useRef12, useCallback as useCallback28 } from "react";
6764
+ import { useEffect as useEffect21, useRef as useRef12, useCallback as useCallback29 } from "react";
6576
6765
  import {
6577
6766
  View as View18,
6578
6767
  Text as Text19,
@@ -6604,19 +6793,19 @@ function EnterArcadePoolSheet({
6604
6793
  const { wallet } = useDubs();
6605
6794
  const mutation = useEnterArcadePool();
6606
6795
  const overlayOpacity = useRef12(new Animated6.Value(0)).current;
6607
- useEffect20(() => {
6796
+ useEffect21(() => {
6608
6797
  Animated6.timing(overlayOpacity, {
6609
6798
  toValue: visible ? 1 : 0,
6610
6799
  duration: 250,
6611
6800
  useNativeDriver: true
6612
6801
  }).start();
6613
6802
  }, [visible, overlayOpacity]);
6614
- useEffect20(() => {
6803
+ useEffect21(() => {
6615
6804
  if (visible) {
6616
6805
  mutation.reset();
6617
6806
  }
6618
6807
  }, [visible]);
6619
- useEffect20(() => {
6808
+ useEffect21(() => {
6620
6809
  if (mutation.status === "success" && mutation.data) {
6621
6810
  onSuccess?.(mutation.data);
6622
6811
  const timer = setTimeout(() => {
@@ -6625,7 +6814,7 @@ function EnterArcadePoolSheet({
6625
6814
  return () => clearTimeout(timer);
6626
6815
  }
6627
6816
  }, [mutation.status, mutation.data]);
6628
- useEffect20(() => {
6817
+ useEffect21(() => {
6629
6818
  if (mutation.status === "error" && mutation.error) {
6630
6819
  onError?.(mutation.error);
6631
6820
  }
@@ -6637,7 +6826,7 @@ function EnterArcadePoolSheet({
6637
6826
  const potSol = (pool.buy_in_lamports * Number(totalBuyIns) / 1e9).toFixed(4);
6638
6827
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
6639
6828
  const canJoin = !isMutating && mutation.status !== "success";
6640
- const handleJoin = useCallback28(async () => {
6829
+ const handleJoin = useCallback29(async () => {
6641
6830
  if (!wallet.publicKey) return;
6642
6831
  try {
6643
6832
  await mutation.execute(pool.id);
@@ -6788,7 +6977,7 @@ var styles18 = StyleSheet19.create({
6788
6977
  });
6789
6978
 
6790
6979
  // src/ui/game/ArcadeLeaderboardSheet.tsx
6791
- import { useEffect as useEffect21, useRef as useRef13 } from "react";
6980
+ import { useEffect as useEffect22, useRef as useRef13 } from "react";
6792
6981
  import {
6793
6982
  View as View19,
6794
6983
  Text as Text20,
@@ -6817,14 +7006,14 @@ function ArcadeLeaderboardSheet({
6817
7006
  const t = useDubsTheme();
6818
7007
  const { pool, leaderboard, stats, loading, refetch } = useArcadePool(poolId);
6819
7008
  const overlayOpacity = useRef13(new Animated7.Value(0)).current;
6820
- useEffect21(() => {
7009
+ useEffect22(() => {
6821
7010
  Animated7.timing(overlayOpacity, {
6822
7011
  toValue: visible ? 1 : 0,
6823
7012
  duration: 250,
6824
7013
  useNativeDriver: true
6825
7014
  }).start();
6826
7015
  }, [visible, overlayOpacity]);
6827
- useEffect21(() => {
7016
+ useEffect22(() => {
6828
7017
  if (visible) refetch();
6829
7018
  }, [visible]);
6830
7019
  const renderItem = ({ item, index }) => {
@@ -6971,7 +7160,7 @@ var styles19 = StyleSheet20.create({
6971
7160
  });
6972
7161
 
6973
7162
  // src/ui/game/CreateGameSheet.tsx
6974
- import { useState as useState34, useEffect as useEffect22, useRef as useRef14, useCallback as useCallback29 } from "react";
7163
+ import { useState as useState35, useEffect as useEffect23, useRef as useRef14, useCallback as useCallback30 } from "react";
6975
7164
  import {
6976
7165
  View as View20,
6977
7166
  Text as Text21,
@@ -7010,20 +7199,20 @@ function CreateGameSheet({
7010
7199
  const t = useDubsTheme();
7011
7200
  const { wallet } = useDubs();
7012
7201
  const mutation = useCreateGame();
7013
- const [selectedTeam, setSelectedTeam] = useState34(null);
7014
- const [wager, setWager] = useState34(0.01);
7015
- const [showSuccess, setShowSuccess] = useState34(false);
7202
+ const [selectedTeam, setSelectedTeam] = useState35(null);
7203
+ const [wager, setWager] = useState35(0.01);
7204
+ const [showSuccess, setShowSuccess] = useState35(false);
7016
7205
  const overlayOpacity = useRef14(new Animated8.Value(0)).current;
7017
7206
  const successScale = useRef14(new Animated8.Value(0)).current;
7018
7207
  const successOpacity = useRef14(new Animated8.Value(0)).current;
7019
- useEffect22(() => {
7208
+ useEffect23(() => {
7020
7209
  Animated8.timing(overlayOpacity, {
7021
7210
  toValue: visible ? 1 : 0,
7022
7211
  duration: 250,
7023
7212
  useNativeDriver: true
7024
7213
  }).start();
7025
7214
  }, [visible]);
7026
- useEffect22(() => {
7215
+ useEffect23(() => {
7027
7216
  if (visible) {
7028
7217
  setSelectedTeam(null);
7029
7218
  setWager(0.01);
@@ -7033,7 +7222,7 @@ function CreateGameSheet({
7033
7222
  mutation.reset();
7034
7223
  }
7035
7224
  }, [visible]);
7036
- useEffect22(() => {
7225
+ useEffect23(() => {
7037
7226
  if (mutation.status === "success" && mutation.data) {
7038
7227
  setShowSuccess(true);
7039
7228
  onSuccess?.(mutation.data);
@@ -7050,7 +7239,7 @@ function CreateGameSheet({
7050
7239
  return () => clearTimeout(timer);
7051
7240
  }
7052
7241
  }, [mutation.status, mutation.data]);
7053
- useEffect22(() => {
7242
+ useEffect23(() => {
7054
7243
  if (mutation.status === "error" && mutation.error) {
7055
7244
  onError?.(mutation.error);
7056
7245
  }
@@ -7060,7 +7249,7 @@ function CreateGameSheet({
7060
7249
  const awayName = shortName ? shortName(opponents[1]?.name) : opponents[1]?.name || "Away";
7061
7250
  const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
7062
7251
  const canCreate = selectedTeam !== null && !isMutating && mutation.status !== "success";
7063
- const handleCreate = useCallback29(async () => {
7252
+ const handleCreate = useCallback30(async () => {
7064
7253
  if (!selectedTeam || !wallet.publicKey) return;
7065
7254
  try {
7066
7255
  await mutation.execute({
@@ -7264,6 +7453,7 @@ export {
7264
7453
  useJoinGame,
7265
7454
  useNetworkGames,
7266
7455
  usePushNotifications,
7456
+ useShorts,
7267
7457
  useUFCFightCard,
7268
7458
  useUFCFighterDetail
7269
7459
  };