@dubsdotapp/expo 0.3.2 → 0.3.3
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 +119 -1
- package/dist/index.d.ts +119 -1
- package/dist/index.js +310 -111
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +291 -95
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -62,6 +62,9 @@ __export(index_exports, {
|
|
|
62
62
|
parseSolanaError: () => parseSolanaError,
|
|
63
63
|
signAndSendBase64Transaction: () => signAndSendBase64Transaction,
|
|
64
64
|
useAppConfig: () => useAppConfig,
|
|
65
|
+
useArcadeGame: () => useArcadeGame,
|
|
66
|
+
useArcadePool: () => useArcadePool,
|
|
67
|
+
useArcadePools: () => useArcadePools,
|
|
65
68
|
useAuth: () => useAuth,
|
|
66
69
|
useClaim: () => useClaim,
|
|
67
70
|
useCreateCustomGame: () => useCreateCustomGame,
|
|
@@ -585,6 +588,67 @@ var DubsClient = class {
|
|
|
585
588
|
getErrorCodesLocal() {
|
|
586
589
|
return { ...SOLANA_PROGRAM_ERRORS };
|
|
587
590
|
}
|
|
591
|
+
// ── Arcade Pools ──
|
|
592
|
+
async getArcadePools(params) {
|
|
593
|
+
const qs = new URLSearchParams();
|
|
594
|
+
if (params?.gameSlug) qs.set("gameSlug", params.gameSlug);
|
|
595
|
+
if (params?.status) qs.set("status", params.status);
|
|
596
|
+
const query = qs.toString();
|
|
597
|
+
const res = await this.request(
|
|
598
|
+
"GET",
|
|
599
|
+
`/arcade/pools${query ? `?${query}` : ""}`
|
|
600
|
+
);
|
|
601
|
+
return res.pools;
|
|
602
|
+
}
|
|
603
|
+
async getArcadePool(poolId) {
|
|
604
|
+
const res = await this.request(
|
|
605
|
+
"GET",
|
|
606
|
+
`/arcade/pools/${poolId}`
|
|
607
|
+
);
|
|
608
|
+
return { pool: res.pool, stats: res.stats };
|
|
609
|
+
}
|
|
610
|
+
async enterArcadePool(poolId, params) {
|
|
611
|
+
const res = await this.request(
|
|
612
|
+
"POST",
|
|
613
|
+
`/arcade/pools/${poolId}/enter`,
|
|
614
|
+
params
|
|
615
|
+
);
|
|
616
|
+
return res.entry;
|
|
617
|
+
}
|
|
618
|
+
async startArcadeAttempt(poolId, walletAddress) {
|
|
619
|
+
const res = await this.request(
|
|
620
|
+
"POST",
|
|
621
|
+
`/arcade/pools/${poolId}/start-attempt`,
|
|
622
|
+
{ walletAddress }
|
|
623
|
+
);
|
|
624
|
+
return { sessionToken: res.sessionToken, attemptNumber: res.attemptNumber, livesRemaining: res.livesRemaining };
|
|
625
|
+
}
|
|
626
|
+
async submitArcadeScore(poolId, params) {
|
|
627
|
+
const res = await this.request(
|
|
628
|
+
"POST",
|
|
629
|
+
`/arcade/pools/${poolId}/submit-score`,
|
|
630
|
+
params
|
|
631
|
+
);
|
|
632
|
+
return { score: res.score, bestScore: res.bestScore, livesUsed: res.livesUsed, isNewBest: res.isNewBest };
|
|
633
|
+
}
|
|
634
|
+
async getArcadeLeaderboard(poolId, params) {
|
|
635
|
+
const qs = new URLSearchParams();
|
|
636
|
+
if (params?.limit != null) qs.set("limit", String(params.limit));
|
|
637
|
+
if (params?.offset != null) qs.set("offset", String(params.offset));
|
|
638
|
+
const query = qs.toString();
|
|
639
|
+
const res = await this.request(
|
|
640
|
+
"GET",
|
|
641
|
+
`/arcade/pools/${poolId}/leaderboard${query ? `?${query}` : ""}`
|
|
642
|
+
);
|
|
643
|
+
return res.leaderboard;
|
|
644
|
+
}
|
|
645
|
+
async getArcadeEntry(poolId, walletAddress) {
|
|
646
|
+
const res = await this.request(
|
|
647
|
+
"GET",
|
|
648
|
+
`/arcade/pools/${poolId}/my-entry?walletAddress=${encodeURIComponent(walletAddress)}`
|
|
649
|
+
);
|
|
650
|
+
return res.entry;
|
|
651
|
+
}
|
|
588
652
|
// ── App Config ──
|
|
589
653
|
/** Fetch the app's UI customization config (accent color, icon, tagline, environment) */
|
|
590
654
|
async getAppConfig() {
|
|
@@ -636,7 +700,7 @@ function createSecureStoreStorage() {
|
|
|
636
700
|
}
|
|
637
701
|
|
|
638
702
|
// src/provider.tsx
|
|
639
|
-
var
|
|
703
|
+
var import_react21 = require("react");
|
|
640
704
|
|
|
641
705
|
// src/ui/theme.ts
|
|
642
706
|
var import_react = require("react");
|
|
@@ -1694,7 +1758,7 @@ function ManagedWalletProvider({
|
|
|
1694
1758
|
}
|
|
1695
1759
|
|
|
1696
1760
|
// src/ui/AuthGate.tsx
|
|
1697
|
-
var
|
|
1761
|
+
var import_react20 = __toESM(require("react"));
|
|
1698
1762
|
var import_react_native8 = require("react-native");
|
|
1699
1763
|
|
|
1700
1764
|
// src/hooks/useEvents.ts
|
|
@@ -2526,6 +2590,138 @@ function usePushNotifications() {
|
|
|
2526
2590
|
};
|
|
2527
2591
|
}
|
|
2528
2592
|
|
|
2593
|
+
// src/hooks/useArcadePools.ts
|
|
2594
|
+
var import_react17 = require("react");
|
|
2595
|
+
function useArcadePools(gameSlug) {
|
|
2596
|
+
const { client } = useDubs();
|
|
2597
|
+
const [pools, setPools] = (0, import_react17.useState)([]);
|
|
2598
|
+
const [loading, setLoading] = (0, import_react17.useState)(false);
|
|
2599
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2600
|
+
const fetch2 = (0, import_react17.useCallback)(async () => {
|
|
2601
|
+
setLoading(true);
|
|
2602
|
+
setError(null);
|
|
2603
|
+
try {
|
|
2604
|
+
const result = await client.getArcadePools({ gameSlug });
|
|
2605
|
+
setPools(result);
|
|
2606
|
+
} catch (err) {
|
|
2607
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
2608
|
+
} finally {
|
|
2609
|
+
setLoading(false);
|
|
2610
|
+
}
|
|
2611
|
+
}, [client, gameSlug]);
|
|
2612
|
+
(0, import_react17.useEffect)(() => {
|
|
2613
|
+
fetch2();
|
|
2614
|
+
}, [fetch2]);
|
|
2615
|
+
return { pools, loading, error, refetch: fetch2 };
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
// src/hooks/useArcadePool.ts
|
|
2619
|
+
var import_react18 = require("react");
|
|
2620
|
+
function useArcadePool(poolId) {
|
|
2621
|
+
const { client } = useDubs();
|
|
2622
|
+
const [pool, setPool] = (0, import_react18.useState)(null);
|
|
2623
|
+
const [stats, setStats] = (0, import_react18.useState)(null);
|
|
2624
|
+
const [leaderboard, setLeaderboard] = (0, import_react18.useState)([]);
|
|
2625
|
+
const [loading, setLoading] = (0, import_react18.useState)(false);
|
|
2626
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
2627
|
+
const fetch2 = (0, import_react18.useCallback)(async () => {
|
|
2628
|
+
if (!poolId) return;
|
|
2629
|
+
setLoading(true);
|
|
2630
|
+
setError(null);
|
|
2631
|
+
try {
|
|
2632
|
+
const [poolRes, lb] = await Promise.all([
|
|
2633
|
+
client.getArcadePool(poolId),
|
|
2634
|
+
client.getArcadeLeaderboard(poolId)
|
|
2635
|
+
]);
|
|
2636
|
+
setPool(poolRes.pool);
|
|
2637
|
+
setStats(poolRes.stats);
|
|
2638
|
+
setLeaderboard(lb);
|
|
2639
|
+
} catch (err) {
|
|
2640
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
2641
|
+
} finally {
|
|
2642
|
+
setLoading(false);
|
|
2643
|
+
}
|
|
2644
|
+
}, [client, poolId]);
|
|
2645
|
+
(0, import_react18.useEffect)(() => {
|
|
2646
|
+
fetch2();
|
|
2647
|
+
}, [fetch2]);
|
|
2648
|
+
return { pool, stats, leaderboard, loading, error, refetch: fetch2 };
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
// src/hooks/useArcadeGame.ts
|
|
2652
|
+
var import_react19 = require("react");
|
|
2653
|
+
function useArcadeGame(poolId, maxLives = 3) {
|
|
2654
|
+
const { client } = useDubs();
|
|
2655
|
+
const { user } = useAuth();
|
|
2656
|
+
const [entry, setEntry] = (0, import_react19.useState)(null);
|
|
2657
|
+
const [loading, setLoading] = (0, import_react19.useState)(false);
|
|
2658
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
2659
|
+
const walletAddress = user?.walletAddress || "";
|
|
2660
|
+
const refreshEntry = (0, import_react19.useCallback)(async () => {
|
|
2661
|
+
if (!poolId || !walletAddress) return;
|
|
2662
|
+
setLoading(true);
|
|
2663
|
+
setError(null);
|
|
2664
|
+
try {
|
|
2665
|
+
const e = await client.getArcadeEntry(poolId, walletAddress);
|
|
2666
|
+
setEntry(e);
|
|
2667
|
+
} catch (err) {
|
|
2668
|
+
if (err instanceof Error && err.message.includes("No entry found")) {
|
|
2669
|
+
setEntry(null);
|
|
2670
|
+
} else {
|
|
2671
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
2672
|
+
}
|
|
2673
|
+
} finally {
|
|
2674
|
+
setLoading(false);
|
|
2675
|
+
}
|
|
2676
|
+
}, [client, poolId, walletAddress]);
|
|
2677
|
+
const startAttempt = (0, import_react19.useCallback)(async () => {
|
|
2678
|
+
if (!poolId || !walletAddress) throw new Error("Not ready");
|
|
2679
|
+
setError(null);
|
|
2680
|
+
try {
|
|
2681
|
+
const result = await client.startArcadeAttempt(poolId, walletAddress);
|
|
2682
|
+
return result;
|
|
2683
|
+
} catch (err) {
|
|
2684
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
2685
|
+
setError(e);
|
|
2686
|
+
throw e;
|
|
2687
|
+
}
|
|
2688
|
+
}, [client, poolId, walletAddress]);
|
|
2689
|
+
const submitScore = (0, import_react19.useCallback)(async (sessionToken, score, durationMs) => {
|
|
2690
|
+
if (!poolId || !walletAddress) throw new Error("Not ready");
|
|
2691
|
+
setError(null);
|
|
2692
|
+
try {
|
|
2693
|
+
const result = await client.submitArcadeScore(poolId, {
|
|
2694
|
+
walletAddress,
|
|
2695
|
+
sessionToken,
|
|
2696
|
+
score,
|
|
2697
|
+
durationMs
|
|
2698
|
+
});
|
|
2699
|
+
setEntry((prev) => prev ? {
|
|
2700
|
+
...prev,
|
|
2701
|
+
best_score: result.bestScore,
|
|
2702
|
+
lives_used: result.livesUsed
|
|
2703
|
+
} : prev);
|
|
2704
|
+
return result;
|
|
2705
|
+
} catch (err) {
|
|
2706
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
2707
|
+
setError(e);
|
|
2708
|
+
throw e;
|
|
2709
|
+
}
|
|
2710
|
+
}, [client, poolId, walletAddress]);
|
|
2711
|
+
const livesRemaining = entry ? maxLives - entry.lives_used : maxLives;
|
|
2712
|
+
const bestScore = entry?.best_score || 0;
|
|
2713
|
+
return {
|
|
2714
|
+
entry,
|
|
2715
|
+
livesRemaining,
|
|
2716
|
+
bestScore,
|
|
2717
|
+
loading,
|
|
2718
|
+
error,
|
|
2719
|
+
refreshEntry,
|
|
2720
|
+
startAttempt,
|
|
2721
|
+
submitScore
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2529
2725
|
// src/ui/AvatarEditor.tsx
|
|
2530
2726
|
var import_react_native7 = require("react-native");
|
|
2531
2727
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -2686,11 +2882,11 @@ function AuthGate({
|
|
|
2686
2882
|
}) {
|
|
2687
2883
|
const { client, pushEnabled } = useDubs();
|
|
2688
2884
|
const auth = useAuth();
|
|
2689
|
-
const [phase, setPhase] = (0,
|
|
2690
|
-
const [registrationPhase, setRegistrationPhase] = (0,
|
|
2691
|
-
const [showPushSetup, setShowPushSetup] = (0,
|
|
2692
|
-
const [isRestoredSession, setIsRestoredSession] = (0,
|
|
2693
|
-
(0,
|
|
2885
|
+
const [phase, setPhase] = (0, import_react20.useState)("init");
|
|
2886
|
+
const [registrationPhase, setRegistrationPhase] = (0, import_react20.useState)(false);
|
|
2887
|
+
const [showPushSetup, setShowPushSetup] = (0, import_react20.useState)(false);
|
|
2888
|
+
const [isRestoredSession, setIsRestoredSession] = (0, import_react20.useState)(false);
|
|
2889
|
+
(0, import_react20.useEffect)(() => {
|
|
2694
2890
|
let cancelled = false;
|
|
2695
2891
|
(async () => {
|
|
2696
2892
|
try {
|
|
@@ -2717,23 +2913,23 @@ function AuthGate({
|
|
|
2717
2913
|
cancelled = true;
|
|
2718
2914
|
};
|
|
2719
2915
|
}, []);
|
|
2720
|
-
(0,
|
|
2916
|
+
(0, import_react20.useEffect)(() => {
|
|
2721
2917
|
if (auth.status === "needsRegistration") setRegistrationPhase(true);
|
|
2722
2918
|
}, [auth.status]);
|
|
2723
|
-
(0,
|
|
2919
|
+
(0, import_react20.useEffect)(() => {
|
|
2724
2920
|
if (pushEnabled && auth.status === "authenticated" && registrationPhase && !isRestoredSession) {
|
|
2725
2921
|
setShowPushSetup(true);
|
|
2726
2922
|
}
|
|
2727
2923
|
}, [pushEnabled, auth.status, registrationPhase, isRestoredSession]);
|
|
2728
|
-
(0,
|
|
2924
|
+
(0, import_react20.useEffect)(() => {
|
|
2729
2925
|
if (auth.token) onSaveToken(auth.token);
|
|
2730
2926
|
}, [auth.token]);
|
|
2731
|
-
const retry = (0,
|
|
2927
|
+
const retry = (0, import_react20.useCallback)(() => {
|
|
2732
2928
|
setRegistrationPhase(false);
|
|
2733
2929
|
auth.reset();
|
|
2734
2930
|
auth.authenticate();
|
|
2735
2931
|
}, [auth]);
|
|
2736
|
-
const handleRegister = (0,
|
|
2932
|
+
const handleRegister = (0, import_react20.useCallback)(
|
|
2737
2933
|
(username, referralCode, avatarUrl) => {
|
|
2738
2934
|
auth.register(username, referralCode, avatarUrl);
|
|
2739
2935
|
},
|
|
@@ -2825,7 +3021,7 @@ function DefaultErrorScreen({ error, onRetry, appName, accentColor }) {
|
|
|
2825
3021
|
function StepIndicator({ currentStep }) {
|
|
2826
3022
|
const t = useDubsTheme();
|
|
2827
3023
|
const steps = [0, 1, 2, 3];
|
|
2828
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: s.stepRow, children: steps.map((i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
3024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: s.stepRow, children: steps.map((i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react20.default.Fragment, { children: [
|
|
2829
3025
|
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: [s.stepLine, { backgroundColor: i <= currentStep ? t.success : t.border }] }),
|
|
2830
3026
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2831
3027
|
import_react_native8.View,
|
|
@@ -2849,20 +3045,20 @@ function DefaultRegistrationScreen({
|
|
|
2849
3045
|
}) {
|
|
2850
3046
|
const t = useDubsTheme();
|
|
2851
3047
|
const accent = accentColor || t.accent;
|
|
2852
|
-
const [step, setStep] = (0,
|
|
2853
|
-
const [avatarSeed, setAvatarSeed] = (0,
|
|
2854
|
-
const [avatarStyle, setAvatarStyle] = (0,
|
|
2855
|
-
const [avatarBg, setAvatarBg] = (0,
|
|
2856
|
-
const [showStyles, setShowStyles] = (0,
|
|
2857
|
-
const [username, setUsername] = (0,
|
|
2858
|
-
const [referralCode, setReferralCode] = (0,
|
|
2859
|
-
const [checking, setChecking] = (0,
|
|
2860
|
-
const [availability, setAvailability] = (0,
|
|
2861
|
-
const debounceRef = (0,
|
|
2862
|
-
const fadeAnim = (0,
|
|
2863
|
-
const slideAnim = (0,
|
|
3048
|
+
const [step, setStep] = (0, import_react20.useState)(0);
|
|
3049
|
+
const [avatarSeed, setAvatarSeed] = (0, import_react20.useState)(generateSeed);
|
|
3050
|
+
const [avatarStyle, setAvatarStyle] = (0, import_react20.useState)("adventurer");
|
|
3051
|
+
const [avatarBg, setAvatarBg] = (0, import_react20.useState)("1a1a2e");
|
|
3052
|
+
const [showStyles, setShowStyles] = (0, import_react20.useState)(false);
|
|
3053
|
+
const [username, setUsername] = (0, import_react20.useState)("");
|
|
3054
|
+
const [referralCode, setReferralCode] = (0, import_react20.useState)("");
|
|
3055
|
+
const [checking, setChecking] = (0, import_react20.useState)(false);
|
|
3056
|
+
const [availability, setAvailability] = (0, import_react20.useState)(null);
|
|
3057
|
+
const debounceRef = (0, import_react20.useRef)(null);
|
|
3058
|
+
const fadeAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(1)).current;
|
|
3059
|
+
const slideAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(0)).current;
|
|
2864
3060
|
const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);
|
|
2865
|
-
(0,
|
|
3061
|
+
(0, import_react20.useEffect)(() => {
|
|
2866
3062
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
2867
3063
|
const trimmed = username.trim();
|
|
2868
3064
|
if (trimmed.length < 3) {
|
|
@@ -2885,7 +3081,7 @@ function DefaultRegistrationScreen({
|
|
|
2885
3081
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
2886
3082
|
};
|
|
2887
3083
|
}, [username, client]);
|
|
2888
|
-
const animateToStep = (0,
|
|
3084
|
+
const animateToStep = (0, import_react20.useCallback)((newStep) => {
|
|
2889
3085
|
const dir = newStep > step ? 1 : -1;
|
|
2890
3086
|
import_react_native8.Keyboard.dismiss();
|
|
2891
3087
|
import_react_native8.Animated.parallel([
|
|
@@ -3124,8 +3320,8 @@ function DefaultRegistrationScreen({
|
|
|
3124
3320
|
}
|
|
3125
3321
|
function PushTokenRestorer() {
|
|
3126
3322
|
const push = usePushNotifications();
|
|
3127
|
-
const restored = (0,
|
|
3128
|
-
(0,
|
|
3323
|
+
const restored = (0, import_react20.useRef)(false);
|
|
3324
|
+
(0, import_react20.useEffect)(() => {
|
|
3129
3325
|
if (restored.current) return;
|
|
3130
3326
|
restored.current = true;
|
|
3131
3327
|
push.restoreIfGranted();
|
|
@@ -3140,9 +3336,9 @@ function PushSetupScreen({
|
|
|
3140
3336
|
const t = useDubsTheme();
|
|
3141
3337
|
const accent = accentColor || t.accent;
|
|
3142
3338
|
const push = usePushNotifications();
|
|
3143
|
-
const fadeAnim = (0,
|
|
3144
|
-
const slideAnim = (0,
|
|
3145
|
-
(0,
|
|
3339
|
+
const fadeAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(0)).current;
|
|
3340
|
+
const slideAnim = (0, import_react20.useRef)(new import_react_native8.Animated.Value(30)).current;
|
|
3341
|
+
(0, import_react20.useEffect)(() => {
|
|
3146
3342
|
import_react_native8.Animated.parallel([
|
|
3147
3343
|
import_react_native8.Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }),
|
|
3148
3344
|
import_react_native8.Animated.timing(slideAnim, { toValue: 0, duration: 300, useNativeDriver: true })
|
|
@@ -3278,7 +3474,7 @@ var s = import_react_native8.StyleSheet.create({
|
|
|
3278
3474
|
|
|
3279
3475
|
// src/provider.tsx
|
|
3280
3476
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3281
|
-
var DubsContext = (0,
|
|
3477
|
+
var DubsContext = (0, import_react21.createContext)(null);
|
|
3282
3478
|
function DubsProvider({
|
|
3283
3479
|
apiKey,
|
|
3284
3480
|
children,
|
|
@@ -3300,11 +3496,11 @@ function DubsProvider({
|
|
|
3300
3496
|
const config = NETWORK_CONFIG[network];
|
|
3301
3497
|
const baseUrl = baseUrlOverride || config.baseUrl;
|
|
3302
3498
|
const rpcUrl = rpcUrlOverride || config.rpcUrl;
|
|
3303
|
-
const client = (0,
|
|
3304
|
-
const storage = (0,
|
|
3305
|
-
const [uiConfig, setUiConfig] = (0,
|
|
3306
|
-
const [resolvedNetwork, setResolvedNetwork] = (0,
|
|
3307
|
-
(0,
|
|
3499
|
+
const client = (0, import_react21.useMemo)(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
|
|
3500
|
+
const storage = (0, import_react21.useMemo)(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
|
|
3501
|
+
const [uiConfig, setUiConfig] = (0, import_react21.useState)(null);
|
|
3502
|
+
const [resolvedNetwork, setResolvedNetwork] = (0, import_react21.useState)(network);
|
|
3503
|
+
(0, import_react21.useEffect)(() => {
|
|
3308
3504
|
client.getAppConfig().then((cfg) => {
|
|
3309
3505
|
console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
|
|
3310
3506
|
setUiConfig(cfg);
|
|
@@ -3320,7 +3516,7 @@ function DubsProvider({
|
|
|
3320
3516
|
const resolvedConfig = NETWORK_CONFIG[resolvedNetwork];
|
|
3321
3517
|
const resolvedRpcUrl = rpcUrlOverride || resolvedConfig.rpcUrl;
|
|
3322
3518
|
const cluster = resolvedConfig.cluster;
|
|
3323
|
-
const connection = (0,
|
|
3519
|
+
const connection = (0, import_react21.useMemo)(() => new import_web34.Connection(resolvedRpcUrl, { commitment: "confirmed" }), [resolvedRpcUrl]);
|
|
3324
3520
|
if (uiConfig === null) return null;
|
|
3325
3521
|
const themeOverrides = {};
|
|
3326
3522
|
if (uiConfig.accentColor) {
|
|
@@ -3396,11 +3592,11 @@ function ManagedInner({
|
|
|
3396
3592
|
children
|
|
3397
3593
|
}) {
|
|
3398
3594
|
const managedDisconnect = useDisconnect();
|
|
3399
|
-
const disconnect = (0,
|
|
3595
|
+
const disconnect = (0, import_react21.useCallback)(async () => {
|
|
3400
3596
|
client.setToken(null);
|
|
3401
3597
|
await managedDisconnect?.();
|
|
3402
3598
|
}, [client, managedDisconnect]);
|
|
3403
|
-
const value = (0,
|
|
3599
|
+
const value = (0, import_react21.useMemo)(
|
|
3404
3600
|
() => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
|
|
3405
3601
|
[client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
|
|
3406
3602
|
);
|
|
@@ -3437,13 +3633,13 @@ function ExternalWalletProvider({
|
|
|
3437
3633
|
pushEnabled,
|
|
3438
3634
|
children
|
|
3439
3635
|
}) {
|
|
3440
|
-
const disconnect = (0,
|
|
3636
|
+
const disconnect = (0, import_react21.useCallback)(async () => {
|
|
3441
3637
|
client.setToken(null);
|
|
3442
3638
|
await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
|
|
3443
3639
|
});
|
|
3444
3640
|
await wallet.disconnect?.();
|
|
3445
3641
|
}, [client, storage, wallet]);
|
|
3446
|
-
const value = (0,
|
|
3642
|
+
const value = (0, import_react21.useMemo)(
|
|
3447
3643
|
() => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
|
|
3448
3644
|
[client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
|
|
3449
3645
|
);
|
|
@@ -3468,19 +3664,19 @@ function ExternalWalletProvider({
|
|
|
3468
3664
|
) });
|
|
3469
3665
|
}
|
|
3470
3666
|
function useDubs() {
|
|
3471
|
-
const ctx = (0,
|
|
3667
|
+
const ctx = (0, import_react21.useContext)(DubsContext);
|
|
3472
3668
|
if (!ctx) {
|
|
3473
3669
|
throw new Error("useDubs must be used within a <DubsProvider>");
|
|
3474
3670
|
}
|
|
3475
3671
|
return ctx;
|
|
3476
3672
|
}
|
|
3477
3673
|
function useAppConfig() {
|
|
3478
|
-
const ctx = (0,
|
|
3674
|
+
const ctx = (0, import_react21.useContext)(DubsContext);
|
|
3479
3675
|
return ctx?.uiConfig || {};
|
|
3480
3676
|
}
|
|
3481
3677
|
|
|
3482
3678
|
// src/ui/UserProfileCard.tsx
|
|
3483
|
-
var
|
|
3679
|
+
var import_react22 = require("react");
|
|
3484
3680
|
var import_react_native9 = require("react-native");
|
|
3485
3681
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
3486
3682
|
function truncateAddress(address, chars = 4) {
|
|
@@ -3500,7 +3696,7 @@ function UserProfileCard({
|
|
|
3500
3696
|
memberSince
|
|
3501
3697
|
}) {
|
|
3502
3698
|
const t = useDubsTheme();
|
|
3503
|
-
const imageUri = (0,
|
|
3699
|
+
const imageUri = (0, import_react22.useMemo)(
|
|
3504
3700
|
() => ensurePngAvatar(avatarUrl) || `https://api.dicebear.com/9.x/avataaars/png?seed=${walletAddress}&size=128`,
|
|
3505
3701
|
[avatarUrl, walletAddress]
|
|
3506
3702
|
);
|
|
@@ -3693,7 +3889,7 @@ var styles4 = import_react_native10.StyleSheet.create({
|
|
|
3693
3889
|
});
|
|
3694
3890
|
|
|
3695
3891
|
// src/ui/UserProfileSheet.tsx
|
|
3696
|
-
var
|
|
3892
|
+
var import_react23 = require("react");
|
|
3697
3893
|
var import_react_native11 = require("react-native");
|
|
3698
3894
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3699
3895
|
function truncateAddress3(address, chars = 4) {
|
|
@@ -3711,31 +3907,31 @@ function UserProfileSheet({
|
|
|
3711
3907
|
const { client } = useDubs();
|
|
3712
3908
|
const { refreshUser } = useAuth();
|
|
3713
3909
|
const push = usePushNotifications();
|
|
3714
|
-
const overlayOpacity = (0,
|
|
3715
|
-
const parsed = (0,
|
|
3716
|
-
const [avatarStyle, setAvatarStyle] = (0,
|
|
3717
|
-
const [avatarSeed, setAvatarSeed] = (0,
|
|
3718
|
-
const [bgColor, setBgColor] = (0,
|
|
3719
|
-
const [saving, setSaving] = (0,
|
|
3720
|
-
const [error, setError] = (0,
|
|
3721
|
-
(0,
|
|
3910
|
+
const overlayOpacity = (0, import_react23.useRef)(new import_react_native11.Animated.Value(0)).current;
|
|
3911
|
+
const parsed = (0, import_react23.useMemo)(() => parseAvatarUrl(user.avatar), [user.avatar]);
|
|
3912
|
+
const [avatarStyle, setAvatarStyle] = (0, import_react23.useState)(parsed.style);
|
|
3913
|
+
const [avatarSeed, setAvatarSeed] = (0, import_react23.useState)(parsed.seed);
|
|
3914
|
+
const [bgColor, setBgColor] = (0, import_react23.useState)(parsed.bg);
|
|
3915
|
+
const [saving, setSaving] = (0, import_react23.useState)(false);
|
|
3916
|
+
const [error, setError] = (0, import_react23.useState)(null);
|
|
3917
|
+
(0, import_react23.useEffect)(() => {
|
|
3722
3918
|
const p = parseAvatarUrl(user.avatar);
|
|
3723
3919
|
setAvatarStyle(p.style);
|
|
3724
3920
|
setAvatarSeed(p.seed);
|
|
3725
3921
|
setBgColor(p.bg);
|
|
3726
3922
|
}, [user.avatar]);
|
|
3727
|
-
(0,
|
|
3923
|
+
(0, import_react23.useEffect)(() => {
|
|
3728
3924
|
import_react_native11.Animated.timing(overlayOpacity, {
|
|
3729
3925
|
toValue: visible ? 1 : 0,
|
|
3730
3926
|
duration: 250,
|
|
3731
3927
|
useNativeDriver: true
|
|
3732
3928
|
}).start();
|
|
3733
3929
|
}, [visible, overlayOpacity]);
|
|
3734
|
-
(0,
|
|
3930
|
+
(0, import_react23.useEffect)(() => {
|
|
3735
3931
|
if (visible) setError(null);
|
|
3736
3932
|
}, [visible]);
|
|
3737
3933
|
const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
|
|
3738
|
-
const saveAvatar = (0,
|
|
3934
|
+
const saveAvatar = (0, import_react23.useCallback)(async (newUrl) => {
|
|
3739
3935
|
setSaving(true);
|
|
3740
3936
|
setError(null);
|
|
3741
3937
|
try {
|
|
@@ -3748,16 +3944,16 @@ function UserProfileSheet({
|
|
|
3748
3944
|
setSaving(false);
|
|
3749
3945
|
}
|
|
3750
3946
|
}, [client, refreshUser, onAvatarUpdated]);
|
|
3751
|
-
const handleStyleChange = (0,
|
|
3947
|
+
const handleStyleChange = (0, import_react23.useCallback)((style) => {
|
|
3752
3948
|
setAvatarStyle(style);
|
|
3753
3949
|
saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
|
|
3754
3950
|
}, [avatarSeed, bgColor, saveAvatar]);
|
|
3755
|
-
const handleShuffle = (0,
|
|
3951
|
+
const handleShuffle = (0, import_react23.useCallback)(() => {
|
|
3756
3952
|
const newSeed = generateSeed();
|
|
3757
3953
|
setAvatarSeed(newSeed);
|
|
3758
3954
|
saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
|
|
3759
3955
|
}, [avatarStyle, bgColor, saveAvatar]);
|
|
3760
|
-
const handleBgChange = (0,
|
|
3956
|
+
const handleBgChange = (0, import_react23.useCallback)((color) => {
|
|
3761
3957
|
setBgColor(color);
|
|
3762
3958
|
saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
|
|
3763
3959
|
}, [avatarStyle, avatarSeed, saveAvatar]);
|
|
@@ -4037,7 +4233,7 @@ var styles5 = import_react_native11.StyleSheet.create({
|
|
|
4037
4233
|
});
|
|
4038
4234
|
|
|
4039
4235
|
// src/ui/game/GamePoster.tsx
|
|
4040
|
-
var
|
|
4236
|
+
var import_react24 = require("react");
|
|
4041
4237
|
var import_react_native12 = require("react-native");
|
|
4042
4238
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4043
4239
|
function computeCountdown(lockTimestamp) {
|
|
@@ -4087,7 +4283,7 @@ function GamePoster({ game, ImageComponent }) {
|
|
|
4087
4283
|
] });
|
|
4088
4284
|
}
|
|
4089
4285
|
function TeamLogoInternal({ url, size, Img }) {
|
|
4090
|
-
const [failed, setFailed] = (0,
|
|
4286
|
+
const [failed, setFailed] = (0, import_react24.useState)(false);
|
|
4091
4287
|
if (!url || failed) {
|
|
4092
4288
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [styles6.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
|
|
4093
4289
|
}
|
|
@@ -4188,7 +4384,7 @@ var styles6 = import_react_native12.StyleSheet.create({
|
|
|
4188
4384
|
});
|
|
4189
4385
|
|
|
4190
4386
|
// src/ui/game/LivePoolsCard.tsx
|
|
4191
|
-
var
|
|
4387
|
+
var import_react25 = require("react");
|
|
4192
4388
|
var import_react_native13 = require("react-native");
|
|
4193
4389
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4194
4390
|
function LivePoolsCard({
|
|
@@ -4204,7 +4400,7 @@ function LivePoolsCard({
|
|
|
4204
4400
|
const homePool = game.homePool || 0;
|
|
4205
4401
|
const awayPool = game.awayPool || 0;
|
|
4206
4402
|
const totalPool = game.totalPool || 0;
|
|
4207
|
-
const { homePercent, awayPercent, homeOdds, awayOdds } = (0,
|
|
4403
|
+
const { homePercent, awayPercent, homeOdds, awayOdds } = (0, import_react25.useMemo)(() => {
|
|
4208
4404
|
return {
|
|
4209
4405
|
homePercent: totalPool > 0 ? homePool / totalPool * 100 : 50,
|
|
4210
4406
|
awayPercent: totalPool > 0 ? awayPool / totalPool * 100 : 50,
|
|
@@ -4267,7 +4463,7 @@ var styles7 = import_react_native13.StyleSheet.create({
|
|
|
4267
4463
|
});
|
|
4268
4464
|
|
|
4269
4465
|
// src/ui/game/PickWinnerCard.tsx
|
|
4270
|
-
var
|
|
4466
|
+
var import_react26 = require("react");
|
|
4271
4467
|
var import_react_native14 = require("react-native");
|
|
4272
4468
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4273
4469
|
function PickWinnerCard({
|
|
@@ -4285,7 +4481,7 @@ function PickWinnerCard({
|
|
|
4285
4481
|
const totalPool = game.totalPool || 0;
|
|
4286
4482
|
const homePool = game.homePool || 0;
|
|
4287
4483
|
const awayPool = game.awayPool || 0;
|
|
4288
|
-
const { homeOdds, awayOdds, homeBets, awayBets } = (0,
|
|
4484
|
+
const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react26.useMemo)(() => ({
|
|
4289
4485
|
homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
|
|
4290
4486
|
awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
|
|
4291
4487
|
homeBets: bettors.filter((b) => b.team === "home").length,
|
|
@@ -4338,7 +4534,7 @@ function TeamOption({
|
|
|
4338
4534
|
ImageComponent,
|
|
4339
4535
|
t
|
|
4340
4536
|
}) {
|
|
4341
|
-
const [imgFailed, setImgFailed] = (0,
|
|
4537
|
+
const [imgFailed, setImgFailed] = (0, import_react26.useState)(false);
|
|
4342
4538
|
const Img = ImageComponent || require("react-native").Image;
|
|
4343
4539
|
const showImage = imageUrl && !imgFailed;
|
|
4344
4540
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
@@ -4379,7 +4575,7 @@ var styles8 = import_react_native14.StyleSheet.create({
|
|
|
4379
4575
|
});
|
|
4380
4576
|
|
|
4381
4577
|
// src/ui/game/PlayersCard.tsx
|
|
4382
|
-
var
|
|
4578
|
+
var import_react27 = require("react");
|
|
4383
4579
|
var import_react_native15 = require("react-native");
|
|
4384
4580
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4385
4581
|
function truncateWallet(addr, chars) {
|
|
@@ -4428,7 +4624,7 @@ function BettorRow({
|
|
|
4428
4624
|
ImageComponent,
|
|
4429
4625
|
t
|
|
4430
4626
|
}) {
|
|
4431
|
-
const [imgFailed, setImgFailed] = (0,
|
|
4627
|
+
const [imgFailed, setImgFailed] = (0, import_react27.useState)(false);
|
|
4432
4628
|
const Img = ImageComponent || require("react-native").Image;
|
|
4433
4629
|
const showAvatar = bettor.avatar && !imgFailed;
|
|
4434
4630
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native15.View, { style: [styles9.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
|
|
@@ -4455,7 +4651,7 @@ var styles9 = import_react_native15.StyleSheet.create({
|
|
|
4455
4651
|
});
|
|
4456
4652
|
|
|
4457
4653
|
// src/ui/game/JoinGameButton.tsx
|
|
4458
|
-
var
|
|
4654
|
+
var import_react28 = require("react");
|
|
4459
4655
|
var import_react_native16 = require("react-native");
|
|
4460
4656
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4461
4657
|
var STATUS_LABELS = {
|
|
@@ -4466,7 +4662,7 @@ var STATUS_LABELS = {
|
|
|
4466
4662
|
};
|
|
4467
4663
|
function JoinGameButton({ game, walletAddress, selectedTeam, status, onJoin }) {
|
|
4468
4664
|
const t = useDubsTheme();
|
|
4469
|
-
const alreadyJoined = (0,
|
|
4665
|
+
const alreadyJoined = (0, import_react28.useMemo)(() => {
|
|
4470
4666
|
if (!walletAddress) return false;
|
|
4471
4667
|
return (game.bettors || []).some((b) => b.wallet === walletAddress);
|
|
4472
4668
|
}, [game.bettors, walletAddress]);
|
|
@@ -4507,7 +4703,7 @@ var styles10 = import_react_native16.StyleSheet.create({
|
|
|
4507
4703
|
});
|
|
4508
4704
|
|
|
4509
4705
|
// src/ui/game/CreateCustomGameSheet.tsx
|
|
4510
|
-
var
|
|
4706
|
+
var import_react29 = require("react");
|
|
4511
4707
|
var import_react_native17 = require("react-native");
|
|
4512
4708
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
4513
4709
|
var STATUS_LABELS2 = {
|
|
@@ -4533,18 +4729,18 @@ function CreateCustomGameSheet({
|
|
|
4533
4729
|
const t = useDubsTheme();
|
|
4534
4730
|
const { wallet } = useDubs();
|
|
4535
4731
|
const mutation = useCreateCustomGame();
|
|
4536
|
-
const [selectedAmount, setSelectedAmount] = (0,
|
|
4537
|
-
const [customAmount, setCustomAmount] = (0,
|
|
4538
|
-
const [isCustom, setIsCustom] = (0,
|
|
4539
|
-
const overlayOpacity = (0,
|
|
4540
|
-
(0,
|
|
4732
|
+
const [selectedAmount, setSelectedAmount] = (0, import_react29.useState)(null);
|
|
4733
|
+
const [customAmount, setCustomAmount] = (0, import_react29.useState)("");
|
|
4734
|
+
const [isCustom, setIsCustom] = (0, import_react29.useState)(false);
|
|
4735
|
+
const overlayOpacity = (0, import_react29.useRef)(new import_react_native17.Animated.Value(0)).current;
|
|
4736
|
+
(0, import_react29.useEffect)(() => {
|
|
4541
4737
|
import_react_native17.Animated.timing(overlayOpacity, {
|
|
4542
4738
|
toValue: visible ? 1 : 0,
|
|
4543
4739
|
duration: 250,
|
|
4544
4740
|
useNativeDriver: true
|
|
4545
4741
|
}).start();
|
|
4546
4742
|
}, [visible, overlayOpacity]);
|
|
4547
|
-
(0,
|
|
4743
|
+
(0, import_react29.useEffect)(() => {
|
|
4548
4744
|
if (visible) {
|
|
4549
4745
|
setSelectedAmount(defaultAmount ?? null);
|
|
4550
4746
|
setCustomAmount("");
|
|
@@ -4552,7 +4748,7 @@ function CreateCustomGameSheet({
|
|
|
4552
4748
|
mutation.reset();
|
|
4553
4749
|
}
|
|
4554
4750
|
}, [visible]);
|
|
4555
|
-
(0,
|
|
4751
|
+
(0, import_react29.useEffect)(() => {
|
|
4556
4752
|
if (mutation.status === "success" && mutation.data) {
|
|
4557
4753
|
onSuccess?.(mutation.data);
|
|
4558
4754
|
const timer = setTimeout(() => {
|
|
@@ -4561,23 +4757,23 @@ function CreateCustomGameSheet({
|
|
|
4561
4757
|
return () => clearTimeout(timer);
|
|
4562
4758
|
}
|
|
4563
4759
|
}, [mutation.status, mutation.data]);
|
|
4564
|
-
(0,
|
|
4760
|
+
(0, import_react29.useEffect)(() => {
|
|
4565
4761
|
if (mutation.status === "error" && mutation.error) {
|
|
4566
4762
|
onError?.(mutation.error);
|
|
4567
4763
|
}
|
|
4568
4764
|
}, [mutation.status, mutation.error]);
|
|
4569
|
-
const handlePresetSelect = (0,
|
|
4765
|
+
const handlePresetSelect = (0, import_react29.useCallback)((amount) => {
|
|
4570
4766
|
setSelectedAmount(amount);
|
|
4571
4767
|
setIsCustom(false);
|
|
4572
4768
|
setCustomAmount("");
|
|
4573
4769
|
onAmountChange?.(amount);
|
|
4574
4770
|
}, [onAmountChange]);
|
|
4575
|
-
const handleCustomSelect = (0,
|
|
4771
|
+
const handleCustomSelect = (0, import_react29.useCallback)(() => {
|
|
4576
4772
|
setIsCustom(true);
|
|
4577
4773
|
setSelectedAmount(null);
|
|
4578
4774
|
onAmountChange?.(null);
|
|
4579
4775
|
}, [onAmountChange]);
|
|
4580
|
-
const handleCustomAmountChange = (0,
|
|
4776
|
+
const handleCustomAmountChange = (0, import_react29.useCallback)((text) => {
|
|
4581
4777
|
const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
|
|
4582
4778
|
setCustomAmount(cleaned);
|
|
4583
4779
|
const parsed = parseFloat(cleaned);
|
|
@@ -4592,7 +4788,7 @@ function CreateCustomGameSheet({
|
|
|
4592
4788
|
const winnerTakes = pot * (1 - fee / 100);
|
|
4593
4789
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
4594
4790
|
const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
|
|
4595
|
-
const handleCreate = (0,
|
|
4791
|
+
const handleCreate = (0, import_react29.useCallback)(async () => {
|
|
4596
4792
|
if (!finalAmount || !wallet.publicKey) return;
|
|
4597
4793
|
try {
|
|
4598
4794
|
await mutation.execute({
|
|
@@ -4861,7 +5057,7 @@ var styles11 = import_react_native17.StyleSheet.create({
|
|
|
4861
5057
|
});
|
|
4862
5058
|
|
|
4863
5059
|
// src/ui/game/JoinGameSheet.tsx
|
|
4864
|
-
var
|
|
5060
|
+
var import_react30 = require("react");
|
|
4865
5061
|
var import_react_native18 = require("react-native");
|
|
4866
5062
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
4867
5063
|
var STATUS_LABELS3 = {
|
|
@@ -4887,22 +5083,22 @@ function JoinGameSheet({
|
|
|
4887
5083
|
const { wallet } = useDubs();
|
|
4888
5084
|
const mutation = useJoinGame();
|
|
4889
5085
|
const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
|
|
4890
|
-
const [selectedTeam, setSelectedTeam] = (0,
|
|
4891
|
-
const overlayOpacity = (0,
|
|
4892
|
-
(0,
|
|
5086
|
+
const [selectedTeam, setSelectedTeam] = (0, import_react30.useState)(null);
|
|
5087
|
+
const overlayOpacity = (0, import_react30.useRef)(new import_react_native18.Animated.Value(0)).current;
|
|
5088
|
+
(0, import_react30.useEffect)(() => {
|
|
4893
5089
|
import_react_native18.Animated.timing(overlayOpacity, {
|
|
4894
5090
|
toValue: visible ? 1 : 0,
|
|
4895
5091
|
duration: 250,
|
|
4896
5092
|
useNativeDriver: true
|
|
4897
5093
|
}).start();
|
|
4898
5094
|
}, [visible, overlayOpacity]);
|
|
4899
|
-
(0,
|
|
5095
|
+
(0, import_react30.useEffect)(() => {
|
|
4900
5096
|
if (visible) {
|
|
4901
5097
|
setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
|
|
4902
5098
|
mutation.reset();
|
|
4903
5099
|
}
|
|
4904
5100
|
}, [visible]);
|
|
4905
|
-
(0,
|
|
5101
|
+
(0, import_react30.useEffect)(() => {
|
|
4906
5102
|
if (mutation.status === "success" && mutation.data) {
|
|
4907
5103
|
onSuccess?.(mutation.data);
|
|
4908
5104
|
const timer = setTimeout(() => {
|
|
@@ -4911,7 +5107,7 @@ function JoinGameSheet({
|
|
|
4911
5107
|
return () => clearTimeout(timer);
|
|
4912
5108
|
}
|
|
4913
5109
|
}, [mutation.status, mutation.data]);
|
|
4914
|
-
(0,
|
|
5110
|
+
(0, import_react30.useEffect)(() => {
|
|
4915
5111
|
if (mutation.status === "error" && mutation.error) {
|
|
4916
5112
|
onError?.(mutation.error);
|
|
4917
5113
|
}
|
|
@@ -4922,7 +5118,7 @@ function JoinGameSheet({
|
|
|
4922
5118
|
const homePool = game.homePool || 0;
|
|
4923
5119
|
const awayPool = game.awayPool || 0;
|
|
4924
5120
|
const buyIn = game.buyIn;
|
|
4925
|
-
const { homeOdds, awayOdds, homeBets, awayBets } = (0,
|
|
5121
|
+
const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react30.useMemo)(() => ({
|
|
4926
5122
|
homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
|
|
4927
5123
|
awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
|
|
4928
5124
|
homeBets: bettors.filter((b) => b.team === "home").length,
|
|
@@ -4934,14 +5130,14 @@ function JoinGameSheet({
|
|
|
4934
5130
|
const homeName = shortName ? shortName(opponents[0]?.name) : opponents[0]?.name || "Home";
|
|
4935
5131
|
const awayName = shortName ? shortName(opponents[1]?.name) : opponents[1]?.name || "Away";
|
|
4936
5132
|
const selectedName = selectedTeam === "home" ? homeName : selectedTeam === "away" ? awayName : "\u2014";
|
|
4937
|
-
const alreadyJoined = (0,
|
|
5133
|
+
const alreadyJoined = (0, import_react30.useMemo)(() => {
|
|
4938
5134
|
if (!wallet.publicKey) return false;
|
|
4939
5135
|
const addr = wallet.publicKey.toBase58();
|
|
4940
5136
|
return bettors.some((b) => b.wallet === addr);
|
|
4941
5137
|
}, [bettors, wallet.publicKey]);
|
|
4942
5138
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
4943
5139
|
const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
|
|
4944
|
-
const handleJoin = (0,
|
|
5140
|
+
const handleJoin = (0, import_react30.useCallback)(async () => {
|
|
4945
5141
|
if (!selectedTeam || !wallet.publicKey) return;
|
|
4946
5142
|
try {
|
|
4947
5143
|
await mutation.execute({
|
|
@@ -5085,7 +5281,7 @@ function TeamButton({
|
|
|
5085
5281
|
ImageComponent,
|
|
5086
5282
|
t
|
|
5087
5283
|
}) {
|
|
5088
|
-
const [imgFailed, setImgFailed] = (0,
|
|
5284
|
+
const [imgFailed, setImgFailed] = (0, import_react30.useState)(false);
|
|
5089
5285
|
const Img = ImageComponent || require("react-native").Image;
|
|
5090
5286
|
const showImage = imageUrl && !imgFailed;
|
|
5091
5287
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
@@ -5262,7 +5458,7 @@ var styles12 = import_react_native18.StyleSheet.create({
|
|
|
5262
5458
|
});
|
|
5263
5459
|
|
|
5264
5460
|
// src/ui/game/ClaimPrizeSheet.tsx
|
|
5265
|
-
var
|
|
5461
|
+
var import_react31 = require("react");
|
|
5266
5462
|
var import_react_native19 = require("react-native");
|
|
5267
5463
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5268
5464
|
var STATUS_LABELS4 = {
|
|
@@ -5283,18 +5479,18 @@ function ClaimPrizeSheet({
|
|
|
5283
5479
|
const t = useDubsTheme();
|
|
5284
5480
|
const { wallet } = useDubs();
|
|
5285
5481
|
const mutation = useClaim();
|
|
5286
|
-
const overlayOpacity = (0,
|
|
5287
|
-
const celebrationScale = (0,
|
|
5288
|
-
const celebrationOpacity = (0,
|
|
5289
|
-
const [showCelebration, setShowCelebration] = (0,
|
|
5290
|
-
(0,
|
|
5482
|
+
const overlayOpacity = (0, import_react31.useRef)(new import_react_native19.Animated.Value(0)).current;
|
|
5483
|
+
const celebrationScale = (0, import_react31.useRef)(new import_react_native19.Animated.Value(0)).current;
|
|
5484
|
+
const celebrationOpacity = (0, import_react31.useRef)(new import_react_native19.Animated.Value(0)).current;
|
|
5485
|
+
const [showCelebration, setShowCelebration] = (0, import_react31.useState)(false);
|
|
5486
|
+
(0, import_react31.useEffect)(() => {
|
|
5291
5487
|
import_react_native19.Animated.timing(overlayOpacity, {
|
|
5292
5488
|
toValue: visible ? 1 : 0,
|
|
5293
5489
|
duration: 250,
|
|
5294
5490
|
useNativeDriver: true
|
|
5295
5491
|
}).start();
|
|
5296
5492
|
}, [visible, overlayOpacity]);
|
|
5297
|
-
(0,
|
|
5493
|
+
(0, import_react31.useEffect)(() => {
|
|
5298
5494
|
if (visible) {
|
|
5299
5495
|
mutation.reset();
|
|
5300
5496
|
setShowCelebration(false);
|
|
@@ -5302,7 +5498,7 @@ function ClaimPrizeSheet({
|
|
|
5302
5498
|
celebrationOpacity.setValue(0);
|
|
5303
5499
|
}
|
|
5304
5500
|
}, [visible]);
|
|
5305
|
-
(0,
|
|
5501
|
+
(0, import_react31.useEffect)(() => {
|
|
5306
5502
|
if (mutation.status === "success" && mutation.data) {
|
|
5307
5503
|
setShowCelebration(true);
|
|
5308
5504
|
import_react_native19.Animated.parallel([
|
|
@@ -5325,14 +5521,14 @@ function ClaimPrizeSheet({
|
|
|
5325
5521
|
return () => clearTimeout(timer);
|
|
5326
5522
|
}
|
|
5327
5523
|
}, [mutation.status, mutation.data]);
|
|
5328
|
-
(0,
|
|
5524
|
+
(0, import_react31.useEffect)(() => {
|
|
5329
5525
|
if (mutation.status === "error" && mutation.error) {
|
|
5330
5526
|
onError?.(mutation.error);
|
|
5331
5527
|
}
|
|
5332
5528
|
}, [mutation.status, mutation.error]);
|
|
5333
5529
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
5334
5530
|
const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
|
|
5335
|
-
const handleClaim = (0,
|
|
5531
|
+
const handleClaim = (0, import_react31.useCallback)(async () => {
|
|
5336
5532
|
if (!wallet.publicKey) return;
|
|
5337
5533
|
try {
|
|
5338
5534
|
await mutation.execute({
|
|
@@ -5565,7 +5761,7 @@ var styles13 = import_react_native19.StyleSheet.create({
|
|
|
5565
5761
|
});
|
|
5566
5762
|
|
|
5567
5763
|
// src/ui/game/ClaimButton.tsx
|
|
5568
|
-
var
|
|
5764
|
+
var import_react32 = require("react");
|
|
5569
5765
|
var import_react_native20 = require("react-native");
|
|
5570
5766
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5571
5767
|
function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
@@ -5573,9 +5769,9 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
|
5573
5769
|
const { wallet } = useDubs();
|
|
5574
5770
|
const game = useGame(gameId);
|
|
5575
5771
|
const claimStatus = useHasClaimed(gameId);
|
|
5576
|
-
const [sheetVisible, setSheetVisible] = (0,
|
|
5772
|
+
const [sheetVisible, setSheetVisible] = (0, import_react32.useState)(false);
|
|
5577
5773
|
const walletAddress = wallet.publicKey?.toBase58() ?? null;
|
|
5578
|
-
const myBet = (0,
|
|
5774
|
+
const myBet = (0, import_react32.useMemo)(() => {
|
|
5579
5775
|
if (!walletAddress || !game.data?.bettors) return null;
|
|
5580
5776
|
return game.data.bettors.find((b) => b.wallet === walletAddress) ?? null;
|
|
5581
5777
|
}, [walletAddress, game.data?.bettors]);
|
|
@@ -5584,7 +5780,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
|
5584
5780
|
const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
|
|
5585
5781
|
const isEligible = myBet != null && isResolved && (isWinner || isRefund);
|
|
5586
5782
|
const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
|
|
5587
|
-
const handleSuccess = (0,
|
|
5783
|
+
const handleSuccess = (0, import_react32.useCallback)(
|
|
5588
5784
|
(result) => {
|
|
5589
5785
|
claimStatus.refetch();
|
|
5590
5786
|
onSuccess?.(result);
|
|
@@ -5703,6 +5899,9 @@ var styles14 = import_react_native20.StyleSheet.create({
|
|
|
5703
5899
|
parseSolanaError,
|
|
5704
5900
|
signAndSendBase64Transaction,
|
|
5705
5901
|
useAppConfig,
|
|
5902
|
+
useArcadeGame,
|
|
5903
|
+
useArcadePool,
|
|
5904
|
+
useArcadePools,
|
|
5706
5905
|
useAuth,
|
|
5707
5906
|
useClaim,
|
|
5708
5907
|
useCreateCustomGame,
|