@dubsdotapp/expo 0.3.3 → 0.3.4
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 +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +387 -111
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +340 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +16 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useEnterArcadePool.ts +79 -0
- package/src/index.ts +6 -1
- package/src/types.ts +15 -0
- package/src/ui/game/EnterArcadePoolSheet.tsx +260 -0
- package/src/ui/game/index.ts +2 -0
- package/src/ui/index.ts +2 -1
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
DubsApiError: () => DubsApiError,
|
|
41
41
|
DubsClient: () => DubsClient,
|
|
42
42
|
DubsProvider: () => DubsProvider,
|
|
43
|
+
EnterArcadePoolSheet: () => EnterArcadePoolSheet,
|
|
43
44
|
GamePoster: () => GamePoster,
|
|
44
45
|
JoinGameButton: () => JoinGameButton,
|
|
45
46
|
JoinGameSheet: () => JoinGameSheet,
|
|
@@ -71,6 +72,7 @@ __export(index_exports, {
|
|
|
71
72
|
useCreateGame: () => useCreateGame,
|
|
72
73
|
useDubs: () => useDubs,
|
|
73
74
|
useDubsTheme: () => useDubsTheme,
|
|
75
|
+
useEnterArcadePool: () => useEnterArcadePool,
|
|
74
76
|
useEvents: () => useEvents,
|
|
75
77
|
useGame: () => useGame,
|
|
76
78
|
useGames: () => useGames,
|
|
@@ -607,6 +609,20 @@ var DubsClient = class {
|
|
|
607
609
|
);
|
|
608
610
|
return { pool: res.pool, stats: res.stats };
|
|
609
611
|
}
|
|
612
|
+
/** Build unsigned entry transaction for an arcade pool */
|
|
613
|
+
async buildArcadeEntry(poolId, walletAddress) {
|
|
614
|
+
const res = await this.request(
|
|
615
|
+
"POST",
|
|
616
|
+
`/arcade/pools/${poolId}/build-enter`,
|
|
617
|
+
{ walletAddress }
|
|
618
|
+
);
|
|
619
|
+
return {
|
|
620
|
+
transaction: res.transaction,
|
|
621
|
+
poolId: res.poolId,
|
|
622
|
+
amount: res.amount,
|
|
623
|
+
destination: res.destination
|
|
624
|
+
};
|
|
625
|
+
}
|
|
610
626
|
async enterArcadePool(poolId, params) {
|
|
611
627
|
const res = await this.request(
|
|
612
628
|
"POST",
|
|
@@ -700,7 +716,7 @@ function createSecureStoreStorage() {
|
|
|
700
716
|
}
|
|
701
717
|
|
|
702
718
|
// src/provider.tsx
|
|
703
|
-
var
|
|
719
|
+
var import_react22 = require("react");
|
|
704
720
|
|
|
705
721
|
// src/ui/theme.ts
|
|
706
722
|
var import_react = require("react");
|
|
@@ -1758,7 +1774,7 @@ function ManagedWalletProvider({
|
|
|
1758
1774
|
}
|
|
1759
1775
|
|
|
1760
1776
|
// src/ui/AuthGate.tsx
|
|
1761
|
-
var
|
|
1777
|
+
var import_react21 = __toESM(require("react"));
|
|
1762
1778
|
var import_react_native8 = require("react-native");
|
|
1763
1779
|
|
|
1764
1780
|
// src/hooks/useEvents.ts
|
|
@@ -2722,6 +2738,64 @@ function useArcadeGame(poolId, maxLives = 3) {
|
|
|
2722
2738
|
};
|
|
2723
2739
|
}
|
|
2724
2740
|
|
|
2741
|
+
// src/hooks/useEnterArcadePool.ts
|
|
2742
|
+
var import_react20 = require("react");
|
|
2743
|
+
function useEnterArcadePool() {
|
|
2744
|
+
const { client, wallet, connection } = useDubs();
|
|
2745
|
+
const { user } = useAuth();
|
|
2746
|
+
const [status, setStatus] = (0, import_react20.useState)("idle");
|
|
2747
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
2748
|
+
const [data, setData] = (0, import_react20.useState)(null);
|
|
2749
|
+
const reset = (0, import_react20.useCallback)(() => {
|
|
2750
|
+
setStatus("idle");
|
|
2751
|
+
setError(null);
|
|
2752
|
+
setData(null);
|
|
2753
|
+
}, []);
|
|
2754
|
+
const execute = (0, import_react20.useCallback)(async (poolId) => {
|
|
2755
|
+
if (!wallet.publicKey) throw new Error("Wallet not connected");
|
|
2756
|
+
const walletAddress = wallet.publicKey.toBase58();
|
|
2757
|
+
setStatus("building");
|
|
2758
|
+
setError(null);
|
|
2759
|
+
setData(null);
|
|
2760
|
+
try {
|
|
2761
|
+
console.log("[useEnterArcadePool] Step 1: Building transaction...", { poolId, walletAddress });
|
|
2762
|
+
const buildResult = await client.buildArcadeEntry(poolId, walletAddress);
|
|
2763
|
+
console.log("[useEnterArcadePool] Step 1 done:", { poolId: buildResult.poolId, amount: buildResult.amount });
|
|
2764
|
+
setStatus("signing");
|
|
2765
|
+
console.log("[useEnterArcadePool] Step 2: Signing and sending...");
|
|
2766
|
+
const signature = await signAndSendBase64Transaction(
|
|
2767
|
+
buildResult.transaction,
|
|
2768
|
+
wallet,
|
|
2769
|
+
connection
|
|
2770
|
+
);
|
|
2771
|
+
console.log("[useEnterArcadePool] Step 2 done. Signature:", signature);
|
|
2772
|
+
setStatus("confirming");
|
|
2773
|
+
console.log("[useEnterArcadePool] Step 3: Confirming with backend...");
|
|
2774
|
+
const entry = await client.enterArcadePool(poolId, {
|
|
2775
|
+
walletAddress,
|
|
2776
|
+
txSignature: signature
|
|
2777
|
+
});
|
|
2778
|
+
console.log("[useEnterArcadePool] Step 3 done. Entry recorded.");
|
|
2779
|
+
const result = {
|
|
2780
|
+
poolId,
|
|
2781
|
+
signature,
|
|
2782
|
+
entry
|
|
2783
|
+
};
|
|
2784
|
+
setData(result);
|
|
2785
|
+
setStatus("success");
|
|
2786
|
+
console.log("[useEnterArcadePool] Complete!");
|
|
2787
|
+
return result;
|
|
2788
|
+
} catch (err) {
|
|
2789
|
+
console.error("[useEnterArcadePool] FAILED at status:", status, err);
|
|
2790
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
2791
|
+
setError(e);
|
|
2792
|
+
setStatus("error");
|
|
2793
|
+
throw e;
|
|
2794
|
+
}
|
|
2795
|
+
}, [client, wallet, connection]);
|
|
2796
|
+
return { execute, status, error, data, reset };
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2725
2799
|
// src/ui/AvatarEditor.tsx
|
|
2726
2800
|
var import_react_native7 = require("react-native");
|
|
2727
2801
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -2882,11 +2956,11 @@ function AuthGate({
|
|
|
2882
2956
|
}) {
|
|
2883
2957
|
const { client, pushEnabled } = useDubs();
|
|
2884
2958
|
const auth = useAuth();
|
|
2885
|
-
const [phase, setPhase] = (0,
|
|
2886
|
-
const [registrationPhase, setRegistrationPhase] = (0,
|
|
2887
|
-
const [showPushSetup, setShowPushSetup] = (0,
|
|
2888
|
-
const [isRestoredSession, setIsRestoredSession] = (0,
|
|
2889
|
-
(0,
|
|
2959
|
+
const [phase, setPhase] = (0, import_react21.useState)("init");
|
|
2960
|
+
const [registrationPhase, setRegistrationPhase] = (0, import_react21.useState)(false);
|
|
2961
|
+
const [showPushSetup, setShowPushSetup] = (0, import_react21.useState)(false);
|
|
2962
|
+
const [isRestoredSession, setIsRestoredSession] = (0, import_react21.useState)(false);
|
|
2963
|
+
(0, import_react21.useEffect)(() => {
|
|
2890
2964
|
let cancelled = false;
|
|
2891
2965
|
(async () => {
|
|
2892
2966
|
try {
|
|
@@ -2913,23 +2987,23 @@ function AuthGate({
|
|
|
2913
2987
|
cancelled = true;
|
|
2914
2988
|
};
|
|
2915
2989
|
}, []);
|
|
2916
|
-
(0,
|
|
2990
|
+
(0, import_react21.useEffect)(() => {
|
|
2917
2991
|
if (auth.status === "needsRegistration") setRegistrationPhase(true);
|
|
2918
2992
|
}, [auth.status]);
|
|
2919
|
-
(0,
|
|
2993
|
+
(0, import_react21.useEffect)(() => {
|
|
2920
2994
|
if (pushEnabled && auth.status === "authenticated" && registrationPhase && !isRestoredSession) {
|
|
2921
2995
|
setShowPushSetup(true);
|
|
2922
2996
|
}
|
|
2923
2997
|
}, [pushEnabled, auth.status, registrationPhase, isRestoredSession]);
|
|
2924
|
-
(0,
|
|
2998
|
+
(0, import_react21.useEffect)(() => {
|
|
2925
2999
|
if (auth.token) onSaveToken(auth.token);
|
|
2926
3000
|
}, [auth.token]);
|
|
2927
|
-
const retry = (0,
|
|
3001
|
+
const retry = (0, import_react21.useCallback)(() => {
|
|
2928
3002
|
setRegistrationPhase(false);
|
|
2929
3003
|
auth.reset();
|
|
2930
3004
|
auth.authenticate();
|
|
2931
3005
|
}, [auth]);
|
|
2932
|
-
const handleRegister = (0,
|
|
3006
|
+
const handleRegister = (0, import_react21.useCallback)(
|
|
2933
3007
|
(username, referralCode, avatarUrl) => {
|
|
2934
3008
|
auth.register(username, referralCode, avatarUrl);
|
|
2935
3009
|
},
|
|
@@ -3021,7 +3095,7 @@ function DefaultErrorScreen({ error, onRetry, appName, accentColor }) {
|
|
|
3021
3095
|
function StepIndicator({ currentStep }) {
|
|
3022
3096
|
const t = useDubsTheme();
|
|
3023
3097
|
const steps = [0, 1, 2, 3];
|
|
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)(
|
|
3098
|
+
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_react21.default.Fragment, { children: [
|
|
3025
3099
|
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native8.View, { style: [s.stepLine, { backgroundColor: i <= currentStep ? t.success : t.border }] }),
|
|
3026
3100
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3027
3101
|
import_react_native8.View,
|
|
@@ -3045,20 +3119,20 @@ function DefaultRegistrationScreen({
|
|
|
3045
3119
|
}) {
|
|
3046
3120
|
const t = useDubsTheme();
|
|
3047
3121
|
const accent = accentColor || t.accent;
|
|
3048
|
-
const [step, setStep] = (0,
|
|
3049
|
-
const [avatarSeed, setAvatarSeed] = (0,
|
|
3050
|
-
const [avatarStyle, setAvatarStyle] = (0,
|
|
3051
|
-
const [avatarBg, setAvatarBg] = (0,
|
|
3052
|
-
const [showStyles, setShowStyles] = (0,
|
|
3053
|
-
const [username, setUsername] = (0,
|
|
3054
|
-
const [referralCode, setReferralCode] = (0,
|
|
3055
|
-
const [checking, setChecking] = (0,
|
|
3056
|
-
const [availability, setAvailability] = (0,
|
|
3057
|
-
const debounceRef = (0,
|
|
3058
|
-
const fadeAnim = (0,
|
|
3059
|
-
const slideAnim = (0,
|
|
3122
|
+
const [step, setStep] = (0, import_react21.useState)(0);
|
|
3123
|
+
const [avatarSeed, setAvatarSeed] = (0, import_react21.useState)(generateSeed);
|
|
3124
|
+
const [avatarStyle, setAvatarStyle] = (0, import_react21.useState)("adventurer");
|
|
3125
|
+
const [avatarBg, setAvatarBg] = (0, import_react21.useState)("1a1a2e");
|
|
3126
|
+
const [showStyles, setShowStyles] = (0, import_react21.useState)(false);
|
|
3127
|
+
const [username, setUsername] = (0, import_react21.useState)("");
|
|
3128
|
+
const [referralCode, setReferralCode] = (0, import_react21.useState)("");
|
|
3129
|
+
const [checking, setChecking] = (0, import_react21.useState)(false);
|
|
3130
|
+
const [availability, setAvailability] = (0, import_react21.useState)(null);
|
|
3131
|
+
const debounceRef = (0, import_react21.useRef)(null);
|
|
3132
|
+
const fadeAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(1)).current;
|
|
3133
|
+
const slideAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(0)).current;
|
|
3060
3134
|
const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);
|
|
3061
|
-
(0,
|
|
3135
|
+
(0, import_react21.useEffect)(() => {
|
|
3062
3136
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
3063
3137
|
const trimmed = username.trim();
|
|
3064
3138
|
if (trimmed.length < 3) {
|
|
@@ -3081,7 +3155,7 @@ function DefaultRegistrationScreen({
|
|
|
3081
3155
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
3082
3156
|
};
|
|
3083
3157
|
}, [username, client]);
|
|
3084
|
-
const animateToStep = (0,
|
|
3158
|
+
const animateToStep = (0, import_react21.useCallback)((newStep) => {
|
|
3085
3159
|
const dir = newStep > step ? 1 : -1;
|
|
3086
3160
|
import_react_native8.Keyboard.dismiss();
|
|
3087
3161
|
import_react_native8.Animated.parallel([
|
|
@@ -3320,8 +3394,8 @@ function DefaultRegistrationScreen({
|
|
|
3320
3394
|
}
|
|
3321
3395
|
function PushTokenRestorer() {
|
|
3322
3396
|
const push = usePushNotifications();
|
|
3323
|
-
const restored = (0,
|
|
3324
|
-
(0,
|
|
3397
|
+
const restored = (0, import_react21.useRef)(false);
|
|
3398
|
+
(0, import_react21.useEffect)(() => {
|
|
3325
3399
|
if (restored.current) return;
|
|
3326
3400
|
restored.current = true;
|
|
3327
3401
|
push.restoreIfGranted();
|
|
@@ -3336,9 +3410,9 @@ function PushSetupScreen({
|
|
|
3336
3410
|
const t = useDubsTheme();
|
|
3337
3411
|
const accent = accentColor || t.accent;
|
|
3338
3412
|
const push = usePushNotifications();
|
|
3339
|
-
const fadeAnim = (0,
|
|
3340
|
-
const slideAnim = (0,
|
|
3341
|
-
(0,
|
|
3413
|
+
const fadeAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(0)).current;
|
|
3414
|
+
const slideAnim = (0, import_react21.useRef)(new import_react_native8.Animated.Value(30)).current;
|
|
3415
|
+
(0, import_react21.useEffect)(() => {
|
|
3342
3416
|
import_react_native8.Animated.parallel([
|
|
3343
3417
|
import_react_native8.Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }),
|
|
3344
3418
|
import_react_native8.Animated.timing(slideAnim, { toValue: 0, duration: 300, useNativeDriver: true })
|
|
@@ -3474,7 +3548,7 @@ var s = import_react_native8.StyleSheet.create({
|
|
|
3474
3548
|
|
|
3475
3549
|
// src/provider.tsx
|
|
3476
3550
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3477
|
-
var DubsContext = (0,
|
|
3551
|
+
var DubsContext = (0, import_react22.createContext)(null);
|
|
3478
3552
|
function DubsProvider({
|
|
3479
3553
|
apiKey,
|
|
3480
3554
|
children,
|
|
@@ -3496,11 +3570,11 @@ function DubsProvider({
|
|
|
3496
3570
|
const config = NETWORK_CONFIG[network];
|
|
3497
3571
|
const baseUrl = baseUrlOverride || config.baseUrl;
|
|
3498
3572
|
const rpcUrl = rpcUrlOverride || config.rpcUrl;
|
|
3499
|
-
const client = (0,
|
|
3500
|
-
const storage = (0,
|
|
3501
|
-
const [uiConfig, setUiConfig] = (0,
|
|
3502
|
-
const [resolvedNetwork, setResolvedNetwork] = (0,
|
|
3503
|
-
(0,
|
|
3573
|
+
const client = (0, import_react22.useMemo)(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
|
|
3574
|
+
const storage = (0, import_react22.useMemo)(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
|
|
3575
|
+
const [uiConfig, setUiConfig] = (0, import_react22.useState)(null);
|
|
3576
|
+
const [resolvedNetwork, setResolvedNetwork] = (0, import_react22.useState)(network);
|
|
3577
|
+
(0, import_react22.useEffect)(() => {
|
|
3504
3578
|
client.getAppConfig().then((cfg) => {
|
|
3505
3579
|
console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
|
|
3506
3580
|
setUiConfig(cfg);
|
|
@@ -3516,7 +3590,7 @@ function DubsProvider({
|
|
|
3516
3590
|
const resolvedConfig = NETWORK_CONFIG[resolvedNetwork];
|
|
3517
3591
|
const resolvedRpcUrl = rpcUrlOverride || resolvedConfig.rpcUrl;
|
|
3518
3592
|
const cluster = resolvedConfig.cluster;
|
|
3519
|
-
const connection = (0,
|
|
3593
|
+
const connection = (0, import_react22.useMemo)(() => new import_web34.Connection(resolvedRpcUrl, { commitment: "confirmed" }), [resolvedRpcUrl]);
|
|
3520
3594
|
if (uiConfig === null) return null;
|
|
3521
3595
|
const themeOverrides = {};
|
|
3522
3596
|
if (uiConfig.accentColor) {
|
|
@@ -3592,11 +3666,11 @@ function ManagedInner({
|
|
|
3592
3666
|
children
|
|
3593
3667
|
}) {
|
|
3594
3668
|
const managedDisconnect = useDisconnect();
|
|
3595
|
-
const disconnect = (0,
|
|
3669
|
+
const disconnect = (0, import_react22.useCallback)(async () => {
|
|
3596
3670
|
client.setToken(null);
|
|
3597
3671
|
await managedDisconnect?.();
|
|
3598
3672
|
}, [client, managedDisconnect]);
|
|
3599
|
-
const value = (0,
|
|
3673
|
+
const value = (0, import_react22.useMemo)(
|
|
3600
3674
|
() => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
|
|
3601
3675
|
[client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
|
|
3602
3676
|
);
|
|
@@ -3633,13 +3707,13 @@ function ExternalWalletProvider({
|
|
|
3633
3707
|
pushEnabled,
|
|
3634
3708
|
children
|
|
3635
3709
|
}) {
|
|
3636
|
-
const disconnect = (0,
|
|
3710
|
+
const disconnect = (0, import_react22.useCallback)(async () => {
|
|
3637
3711
|
client.setToken(null);
|
|
3638
3712
|
await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
|
|
3639
3713
|
});
|
|
3640
3714
|
await wallet.disconnect?.();
|
|
3641
3715
|
}, [client, storage, wallet]);
|
|
3642
|
-
const value = (0,
|
|
3716
|
+
const value = (0, import_react22.useMemo)(
|
|
3643
3717
|
() => ({ client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled }),
|
|
3644
3718
|
[client, wallet, connection, appName, network, disconnect, uiConfig, pushEnabled]
|
|
3645
3719
|
);
|
|
@@ -3664,19 +3738,19 @@ function ExternalWalletProvider({
|
|
|
3664
3738
|
) });
|
|
3665
3739
|
}
|
|
3666
3740
|
function useDubs() {
|
|
3667
|
-
const ctx = (0,
|
|
3741
|
+
const ctx = (0, import_react22.useContext)(DubsContext);
|
|
3668
3742
|
if (!ctx) {
|
|
3669
3743
|
throw new Error("useDubs must be used within a <DubsProvider>");
|
|
3670
3744
|
}
|
|
3671
3745
|
return ctx;
|
|
3672
3746
|
}
|
|
3673
3747
|
function useAppConfig() {
|
|
3674
|
-
const ctx = (0,
|
|
3748
|
+
const ctx = (0, import_react22.useContext)(DubsContext);
|
|
3675
3749
|
return ctx?.uiConfig || {};
|
|
3676
3750
|
}
|
|
3677
3751
|
|
|
3678
3752
|
// src/ui/UserProfileCard.tsx
|
|
3679
|
-
var
|
|
3753
|
+
var import_react23 = require("react");
|
|
3680
3754
|
var import_react_native9 = require("react-native");
|
|
3681
3755
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
3682
3756
|
function truncateAddress(address, chars = 4) {
|
|
@@ -3696,7 +3770,7 @@ function UserProfileCard({
|
|
|
3696
3770
|
memberSince
|
|
3697
3771
|
}) {
|
|
3698
3772
|
const t = useDubsTheme();
|
|
3699
|
-
const imageUri = (0,
|
|
3773
|
+
const imageUri = (0, import_react23.useMemo)(
|
|
3700
3774
|
() => ensurePngAvatar(avatarUrl) || `https://api.dicebear.com/9.x/avataaars/png?seed=${walletAddress}&size=128`,
|
|
3701
3775
|
[avatarUrl, walletAddress]
|
|
3702
3776
|
);
|
|
@@ -3889,7 +3963,7 @@ var styles4 = import_react_native10.StyleSheet.create({
|
|
|
3889
3963
|
});
|
|
3890
3964
|
|
|
3891
3965
|
// src/ui/UserProfileSheet.tsx
|
|
3892
|
-
var
|
|
3966
|
+
var import_react24 = require("react");
|
|
3893
3967
|
var import_react_native11 = require("react-native");
|
|
3894
3968
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3895
3969
|
function truncateAddress3(address, chars = 4) {
|
|
@@ -3907,31 +3981,31 @@ function UserProfileSheet({
|
|
|
3907
3981
|
const { client } = useDubs();
|
|
3908
3982
|
const { refreshUser } = useAuth();
|
|
3909
3983
|
const push = usePushNotifications();
|
|
3910
|
-
const overlayOpacity = (0,
|
|
3911
|
-
const parsed = (0,
|
|
3912
|
-
const [avatarStyle, setAvatarStyle] = (0,
|
|
3913
|
-
const [avatarSeed, setAvatarSeed] = (0,
|
|
3914
|
-
const [bgColor, setBgColor] = (0,
|
|
3915
|
-
const [saving, setSaving] = (0,
|
|
3916
|
-
const [error, setError] = (0,
|
|
3917
|
-
(0,
|
|
3984
|
+
const overlayOpacity = (0, import_react24.useRef)(new import_react_native11.Animated.Value(0)).current;
|
|
3985
|
+
const parsed = (0, import_react24.useMemo)(() => parseAvatarUrl(user.avatar), [user.avatar]);
|
|
3986
|
+
const [avatarStyle, setAvatarStyle] = (0, import_react24.useState)(parsed.style);
|
|
3987
|
+
const [avatarSeed, setAvatarSeed] = (0, import_react24.useState)(parsed.seed);
|
|
3988
|
+
const [bgColor, setBgColor] = (0, import_react24.useState)(parsed.bg);
|
|
3989
|
+
const [saving, setSaving] = (0, import_react24.useState)(false);
|
|
3990
|
+
const [error, setError] = (0, import_react24.useState)(null);
|
|
3991
|
+
(0, import_react24.useEffect)(() => {
|
|
3918
3992
|
const p = parseAvatarUrl(user.avatar);
|
|
3919
3993
|
setAvatarStyle(p.style);
|
|
3920
3994
|
setAvatarSeed(p.seed);
|
|
3921
3995
|
setBgColor(p.bg);
|
|
3922
3996
|
}, [user.avatar]);
|
|
3923
|
-
(0,
|
|
3997
|
+
(0, import_react24.useEffect)(() => {
|
|
3924
3998
|
import_react_native11.Animated.timing(overlayOpacity, {
|
|
3925
3999
|
toValue: visible ? 1 : 0,
|
|
3926
4000
|
duration: 250,
|
|
3927
4001
|
useNativeDriver: true
|
|
3928
4002
|
}).start();
|
|
3929
4003
|
}, [visible, overlayOpacity]);
|
|
3930
|
-
(0,
|
|
4004
|
+
(0, import_react24.useEffect)(() => {
|
|
3931
4005
|
if (visible) setError(null);
|
|
3932
4006
|
}, [visible]);
|
|
3933
4007
|
const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
|
|
3934
|
-
const saveAvatar = (0,
|
|
4008
|
+
const saveAvatar = (0, import_react24.useCallback)(async (newUrl) => {
|
|
3935
4009
|
setSaving(true);
|
|
3936
4010
|
setError(null);
|
|
3937
4011
|
try {
|
|
@@ -3944,16 +4018,16 @@ function UserProfileSheet({
|
|
|
3944
4018
|
setSaving(false);
|
|
3945
4019
|
}
|
|
3946
4020
|
}, [client, refreshUser, onAvatarUpdated]);
|
|
3947
|
-
const handleStyleChange = (0,
|
|
4021
|
+
const handleStyleChange = (0, import_react24.useCallback)((style) => {
|
|
3948
4022
|
setAvatarStyle(style);
|
|
3949
4023
|
saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
|
|
3950
4024
|
}, [avatarSeed, bgColor, saveAvatar]);
|
|
3951
|
-
const handleShuffle = (0,
|
|
4025
|
+
const handleShuffle = (0, import_react24.useCallback)(() => {
|
|
3952
4026
|
const newSeed = generateSeed();
|
|
3953
4027
|
setAvatarSeed(newSeed);
|
|
3954
4028
|
saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
|
|
3955
4029
|
}, [avatarStyle, bgColor, saveAvatar]);
|
|
3956
|
-
const handleBgChange = (0,
|
|
4030
|
+
const handleBgChange = (0, import_react24.useCallback)((color) => {
|
|
3957
4031
|
setBgColor(color);
|
|
3958
4032
|
saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
|
|
3959
4033
|
}, [avatarStyle, avatarSeed, saveAvatar]);
|
|
@@ -4233,7 +4307,7 @@ var styles5 = import_react_native11.StyleSheet.create({
|
|
|
4233
4307
|
});
|
|
4234
4308
|
|
|
4235
4309
|
// src/ui/game/GamePoster.tsx
|
|
4236
|
-
var
|
|
4310
|
+
var import_react25 = require("react");
|
|
4237
4311
|
var import_react_native12 = require("react-native");
|
|
4238
4312
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4239
4313
|
function computeCountdown(lockTimestamp) {
|
|
@@ -4283,7 +4357,7 @@ function GamePoster({ game, ImageComponent }) {
|
|
|
4283
4357
|
] });
|
|
4284
4358
|
}
|
|
4285
4359
|
function TeamLogoInternal({ url, size, Img }) {
|
|
4286
|
-
const [failed, setFailed] = (0,
|
|
4360
|
+
const [failed, setFailed] = (0, import_react25.useState)(false);
|
|
4287
4361
|
if (!url || failed) {
|
|
4288
4362
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [styles6.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
|
|
4289
4363
|
}
|
|
@@ -4384,7 +4458,7 @@ var styles6 = import_react_native12.StyleSheet.create({
|
|
|
4384
4458
|
});
|
|
4385
4459
|
|
|
4386
4460
|
// src/ui/game/LivePoolsCard.tsx
|
|
4387
|
-
var
|
|
4461
|
+
var import_react26 = require("react");
|
|
4388
4462
|
var import_react_native13 = require("react-native");
|
|
4389
4463
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4390
4464
|
function LivePoolsCard({
|
|
@@ -4400,7 +4474,7 @@ function LivePoolsCard({
|
|
|
4400
4474
|
const homePool = game.homePool || 0;
|
|
4401
4475
|
const awayPool = game.awayPool || 0;
|
|
4402
4476
|
const totalPool = game.totalPool || 0;
|
|
4403
|
-
const { homePercent, awayPercent, homeOdds, awayOdds } = (0,
|
|
4477
|
+
const { homePercent, awayPercent, homeOdds, awayOdds } = (0, import_react26.useMemo)(() => {
|
|
4404
4478
|
return {
|
|
4405
4479
|
homePercent: totalPool > 0 ? homePool / totalPool * 100 : 50,
|
|
4406
4480
|
awayPercent: totalPool > 0 ? awayPool / totalPool * 100 : 50,
|
|
@@ -4463,7 +4537,7 @@ var styles7 = import_react_native13.StyleSheet.create({
|
|
|
4463
4537
|
});
|
|
4464
4538
|
|
|
4465
4539
|
// src/ui/game/PickWinnerCard.tsx
|
|
4466
|
-
var
|
|
4540
|
+
var import_react27 = require("react");
|
|
4467
4541
|
var import_react_native14 = require("react-native");
|
|
4468
4542
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4469
4543
|
function PickWinnerCard({
|
|
@@ -4481,7 +4555,7 @@ function PickWinnerCard({
|
|
|
4481
4555
|
const totalPool = game.totalPool || 0;
|
|
4482
4556
|
const homePool = game.homePool || 0;
|
|
4483
4557
|
const awayPool = game.awayPool || 0;
|
|
4484
|
-
const { homeOdds, awayOdds, homeBets, awayBets } = (0,
|
|
4558
|
+
const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react27.useMemo)(() => ({
|
|
4485
4559
|
homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
|
|
4486
4560
|
awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
|
|
4487
4561
|
homeBets: bettors.filter((b) => b.team === "home").length,
|
|
@@ -4534,7 +4608,7 @@ function TeamOption({
|
|
|
4534
4608
|
ImageComponent,
|
|
4535
4609
|
t
|
|
4536
4610
|
}) {
|
|
4537
|
-
const [imgFailed, setImgFailed] = (0,
|
|
4611
|
+
const [imgFailed, setImgFailed] = (0, import_react27.useState)(false);
|
|
4538
4612
|
const Img = ImageComponent || require("react-native").Image;
|
|
4539
4613
|
const showImage = imageUrl && !imgFailed;
|
|
4540
4614
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
@@ -4575,7 +4649,7 @@ var styles8 = import_react_native14.StyleSheet.create({
|
|
|
4575
4649
|
});
|
|
4576
4650
|
|
|
4577
4651
|
// src/ui/game/PlayersCard.tsx
|
|
4578
|
-
var
|
|
4652
|
+
var import_react28 = require("react");
|
|
4579
4653
|
var import_react_native15 = require("react-native");
|
|
4580
4654
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4581
4655
|
function truncateWallet(addr, chars) {
|
|
@@ -4624,7 +4698,7 @@ function BettorRow({
|
|
|
4624
4698
|
ImageComponent,
|
|
4625
4699
|
t
|
|
4626
4700
|
}) {
|
|
4627
|
-
const [imgFailed, setImgFailed] = (0,
|
|
4701
|
+
const [imgFailed, setImgFailed] = (0, import_react28.useState)(false);
|
|
4628
4702
|
const Img = ImageComponent || require("react-native").Image;
|
|
4629
4703
|
const showAvatar = bettor.avatar && !imgFailed;
|
|
4630
4704
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native15.View, { style: [styles9.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
|
|
@@ -4651,7 +4725,7 @@ var styles9 = import_react_native15.StyleSheet.create({
|
|
|
4651
4725
|
});
|
|
4652
4726
|
|
|
4653
4727
|
// src/ui/game/JoinGameButton.tsx
|
|
4654
|
-
var
|
|
4728
|
+
var import_react29 = require("react");
|
|
4655
4729
|
var import_react_native16 = require("react-native");
|
|
4656
4730
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4657
4731
|
var STATUS_LABELS = {
|
|
@@ -4662,7 +4736,7 @@ var STATUS_LABELS = {
|
|
|
4662
4736
|
};
|
|
4663
4737
|
function JoinGameButton({ game, walletAddress, selectedTeam, status, onJoin }) {
|
|
4664
4738
|
const t = useDubsTheme();
|
|
4665
|
-
const alreadyJoined = (0,
|
|
4739
|
+
const alreadyJoined = (0, import_react29.useMemo)(() => {
|
|
4666
4740
|
if (!walletAddress) return false;
|
|
4667
4741
|
return (game.bettors || []).some((b) => b.wallet === walletAddress);
|
|
4668
4742
|
}, [game.bettors, walletAddress]);
|
|
@@ -4703,7 +4777,7 @@ var styles10 = import_react_native16.StyleSheet.create({
|
|
|
4703
4777
|
});
|
|
4704
4778
|
|
|
4705
4779
|
// src/ui/game/CreateCustomGameSheet.tsx
|
|
4706
|
-
var
|
|
4780
|
+
var import_react30 = require("react");
|
|
4707
4781
|
var import_react_native17 = require("react-native");
|
|
4708
4782
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
4709
4783
|
var STATUS_LABELS2 = {
|
|
@@ -4729,18 +4803,18 @@ function CreateCustomGameSheet({
|
|
|
4729
4803
|
const t = useDubsTheme();
|
|
4730
4804
|
const { wallet } = useDubs();
|
|
4731
4805
|
const mutation = useCreateCustomGame();
|
|
4732
|
-
const [selectedAmount, setSelectedAmount] = (0,
|
|
4733
|
-
const [customAmount, setCustomAmount] = (0,
|
|
4734
|
-
const [isCustom, setIsCustom] = (0,
|
|
4735
|
-
const overlayOpacity = (0,
|
|
4736
|
-
(0,
|
|
4806
|
+
const [selectedAmount, setSelectedAmount] = (0, import_react30.useState)(null);
|
|
4807
|
+
const [customAmount, setCustomAmount] = (0, import_react30.useState)("");
|
|
4808
|
+
const [isCustom, setIsCustom] = (0, import_react30.useState)(false);
|
|
4809
|
+
const overlayOpacity = (0, import_react30.useRef)(new import_react_native17.Animated.Value(0)).current;
|
|
4810
|
+
(0, import_react30.useEffect)(() => {
|
|
4737
4811
|
import_react_native17.Animated.timing(overlayOpacity, {
|
|
4738
4812
|
toValue: visible ? 1 : 0,
|
|
4739
4813
|
duration: 250,
|
|
4740
4814
|
useNativeDriver: true
|
|
4741
4815
|
}).start();
|
|
4742
4816
|
}, [visible, overlayOpacity]);
|
|
4743
|
-
(0,
|
|
4817
|
+
(0, import_react30.useEffect)(() => {
|
|
4744
4818
|
if (visible) {
|
|
4745
4819
|
setSelectedAmount(defaultAmount ?? null);
|
|
4746
4820
|
setCustomAmount("");
|
|
@@ -4748,7 +4822,7 @@ function CreateCustomGameSheet({
|
|
|
4748
4822
|
mutation.reset();
|
|
4749
4823
|
}
|
|
4750
4824
|
}, [visible]);
|
|
4751
|
-
(0,
|
|
4825
|
+
(0, import_react30.useEffect)(() => {
|
|
4752
4826
|
if (mutation.status === "success" && mutation.data) {
|
|
4753
4827
|
onSuccess?.(mutation.data);
|
|
4754
4828
|
const timer = setTimeout(() => {
|
|
@@ -4757,23 +4831,23 @@ function CreateCustomGameSheet({
|
|
|
4757
4831
|
return () => clearTimeout(timer);
|
|
4758
4832
|
}
|
|
4759
4833
|
}, [mutation.status, mutation.data]);
|
|
4760
|
-
(0,
|
|
4834
|
+
(0, import_react30.useEffect)(() => {
|
|
4761
4835
|
if (mutation.status === "error" && mutation.error) {
|
|
4762
4836
|
onError?.(mutation.error);
|
|
4763
4837
|
}
|
|
4764
4838
|
}, [mutation.status, mutation.error]);
|
|
4765
|
-
const handlePresetSelect = (0,
|
|
4839
|
+
const handlePresetSelect = (0, import_react30.useCallback)((amount) => {
|
|
4766
4840
|
setSelectedAmount(amount);
|
|
4767
4841
|
setIsCustom(false);
|
|
4768
4842
|
setCustomAmount("");
|
|
4769
4843
|
onAmountChange?.(amount);
|
|
4770
4844
|
}, [onAmountChange]);
|
|
4771
|
-
const handleCustomSelect = (0,
|
|
4845
|
+
const handleCustomSelect = (0, import_react30.useCallback)(() => {
|
|
4772
4846
|
setIsCustom(true);
|
|
4773
4847
|
setSelectedAmount(null);
|
|
4774
4848
|
onAmountChange?.(null);
|
|
4775
4849
|
}, [onAmountChange]);
|
|
4776
|
-
const handleCustomAmountChange = (0,
|
|
4850
|
+
const handleCustomAmountChange = (0, import_react30.useCallback)((text) => {
|
|
4777
4851
|
const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
|
|
4778
4852
|
setCustomAmount(cleaned);
|
|
4779
4853
|
const parsed = parseFloat(cleaned);
|
|
@@ -4788,7 +4862,7 @@ function CreateCustomGameSheet({
|
|
|
4788
4862
|
const winnerTakes = pot * (1 - fee / 100);
|
|
4789
4863
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
4790
4864
|
const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
|
|
4791
|
-
const handleCreate = (0,
|
|
4865
|
+
const handleCreate = (0, import_react30.useCallback)(async () => {
|
|
4792
4866
|
if (!finalAmount || !wallet.publicKey) return;
|
|
4793
4867
|
try {
|
|
4794
4868
|
await mutation.execute({
|
|
@@ -5057,7 +5131,7 @@ var styles11 = import_react_native17.StyleSheet.create({
|
|
|
5057
5131
|
});
|
|
5058
5132
|
|
|
5059
5133
|
// src/ui/game/JoinGameSheet.tsx
|
|
5060
|
-
var
|
|
5134
|
+
var import_react31 = require("react");
|
|
5061
5135
|
var import_react_native18 = require("react-native");
|
|
5062
5136
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5063
5137
|
var STATUS_LABELS3 = {
|
|
@@ -5083,22 +5157,22 @@ function JoinGameSheet({
|
|
|
5083
5157
|
const { wallet } = useDubs();
|
|
5084
5158
|
const mutation = useJoinGame();
|
|
5085
5159
|
const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
|
|
5086
|
-
const [selectedTeam, setSelectedTeam] = (0,
|
|
5087
|
-
const overlayOpacity = (0,
|
|
5088
|
-
(0,
|
|
5160
|
+
const [selectedTeam, setSelectedTeam] = (0, import_react31.useState)(null);
|
|
5161
|
+
const overlayOpacity = (0, import_react31.useRef)(new import_react_native18.Animated.Value(0)).current;
|
|
5162
|
+
(0, import_react31.useEffect)(() => {
|
|
5089
5163
|
import_react_native18.Animated.timing(overlayOpacity, {
|
|
5090
5164
|
toValue: visible ? 1 : 0,
|
|
5091
5165
|
duration: 250,
|
|
5092
5166
|
useNativeDriver: true
|
|
5093
5167
|
}).start();
|
|
5094
5168
|
}, [visible, overlayOpacity]);
|
|
5095
|
-
(0,
|
|
5169
|
+
(0, import_react31.useEffect)(() => {
|
|
5096
5170
|
if (visible) {
|
|
5097
5171
|
setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
|
|
5098
5172
|
mutation.reset();
|
|
5099
5173
|
}
|
|
5100
5174
|
}, [visible]);
|
|
5101
|
-
(0,
|
|
5175
|
+
(0, import_react31.useEffect)(() => {
|
|
5102
5176
|
if (mutation.status === "success" && mutation.data) {
|
|
5103
5177
|
onSuccess?.(mutation.data);
|
|
5104
5178
|
const timer = setTimeout(() => {
|
|
@@ -5107,7 +5181,7 @@ function JoinGameSheet({
|
|
|
5107
5181
|
return () => clearTimeout(timer);
|
|
5108
5182
|
}
|
|
5109
5183
|
}, [mutation.status, mutation.data]);
|
|
5110
|
-
(0,
|
|
5184
|
+
(0, import_react31.useEffect)(() => {
|
|
5111
5185
|
if (mutation.status === "error" && mutation.error) {
|
|
5112
5186
|
onError?.(mutation.error);
|
|
5113
5187
|
}
|
|
@@ -5118,7 +5192,7 @@ function JoinGameSheet({
|
|
|
5118
5192
|
const homePool = game.homePool || 0;
|
|
5119
5193
|
const awayPool = game.awayPool || 0;
|
|
5120
5194
|
const buyIn = game.buyIn;
|
|
5121
|
-
const { homeOdds, awayOdds, homeBets, awayBets } = (0,
|
|
5195
|
+
const { homeOdds, awayOdds, homeBets, awayBets } = (0, import_react31.useMemo)(() => ({
|
|
5122
5196
|
homeOdds: homePool > 0 ? (totalPool / homePool).toFixed(2) : "\u2014",
|
|
5123
5197
|
awayOdds: awayPool > 0 ? (totalPool / awayPool).toFixed(2) : "\u2014",
|
|
5124
5198
|
homeBets: bettors.filter((b) => b.team === "home").length,
|
|
@@ -5130,14 +5204,14 @@ function JoinGameSheet({
|
|
|
5130
5204
|
const homeName = shortName ? shortName(opponents[0]?.name) : opponents[0]?.name || "Home";
|
|
5131
5205
|
const awayName = shortName ? shortName(opponents[1]?.name) : opponents[1]?.name || "Away";
|
|
5132
5206
|
const selectedName = selectedTeam === "home" ? homeName : selectedTeam === "away" ? awayName : "\u2014";
|
|
5133
|
-
const alreadyJoined = (0,
|
|
5207
|
+
const alreadyJoined = (0, import_react31.useMemo)(() => {
|
|
5134
5208
|
if (!wallet.publicKey) return false;
|
|
5135
5209
|
const addr = wallet.publicKey.toBase58();
|
|
5136
5210
|
return bettors.some((b) => b.wallet === addr);
|
|
5137
5211
|
}, [bettors, wallet.publicKey]);
|
|
5138
5212
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
5139
5213
|
const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
|
|
5140
|
-
const handleJoin = (0,
|
|
5214
|
+
const handleJoin = (0, import_react31.useCallback)(async () => {
|
|
5141
5215
|
if (!selectedTeam || !wallet.publicKey) return;
|
|
5142
5216
|
try {
|
|
5143
5217
|
await mutation.execute({
|
|
@@ -5281,7 +5355,7 @@ function TeamButton({
|
|
|
5281
5355
|
ImageComponent,
|
|
5282
5356
|
t
|
|
5283
5357
|
}) {
|
|
5284
|
-
const [imgFailed, setImgFailed] = (0,
|
|
5358
|
+
const [imgFailed, setImgFailed] = (0, import_react31.useState)(false);
|
|
5285
5359
|
const Img = ImageComponent || require("react-native").Image;
|
|
5286
5360
|
const showImage = imageUrl && !imgFailed;
|
|
5287
5361
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
@@ -5458,7 +5532,7 @@ var styles12 = import_react_native18.StyleSheet.create({
|
|
|
5458
5532
|
});
|
|
5459
5533
|
|
|
5460
5534
|
// src/ui/game/ClaimPrizeSheet.tsx
|
|
5461
|
-
var
|
|
5535
|
+
var import_react32 = require("react");
|
|
5462
5536
|
var import_react_native19 = require("react-native");
|
|
5463
5537
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5464
5538
|
var STATUS_LABELS4 = {
|
|
@@ -5479,18 +5553,18 @@ function ClaimPrizeSheet({
|
|
|
5479
5553
|
const t = useDubsTheme();
|
|
5480
5554
|
const { wallet } = useDubs();
|
|
5481
5555
|
const mutation = useClaim();
|
|
5482
|
-
const overlayOpacity = (0,
|
|
5483
|
-
const celebrationScale = (0,
|
|
5484
|
-
const celebrationOpacity = (0,
|
|
5485
|
-
const [showCelebration, setShowCelebration] = (0,
|
|
5486
|
-
(0,
|
|
5556
|
+
const overlayOpacity = (0, import_react32.useRef)(new import_react_native19.Animated.Value(0)).current;
|
|
5557
|
+
const celebrationScale = (0, import_react32.useRef)(new import_react_native19.Animated.Value(0)).current;
|
|
5558
|
+
const celebrationOpacity = (0, import_react32.useRef)(new import_react_native19.Animated.Value(0)).current;
|
|
5559
|
+
const [showCelebration, setShowCelebration] = (0, import_react32.useState)(false);
|
|
5560
|
+
(0, import_react32.useEffect)(() => {
|
|
5487
5561
|
import_react_native19.Animated.timing(overlayOpacity, {
|
|
5488
5562
|
toValue: visible ? 1 : 0,
|
|
5489
5563
|
duration: 250,
|
|
5490
5564
|
useNativeDriver: true
|
|
5491
5565
|
}).start();
|
|
5492
5566
|
}, [visible, overlayOpacity]);
|
|
5493
|
-
(0,
|
|
5567
|
+
(0, import_react32.useEffect)(() => {
|
|
5494
5568
|
if (visible) {
|
|
5495
5569
|
mutation.reset();
|
|
5496
5570
|
setShowCelebration(false);
|
|
@@ -5498,7 +5572,7 @@ function ClaimPrizeSheet({
|
|
|
5498
5572
|
celebrationOpacity.setValue(0);
|
|
5499
5573
|
}
|
|
5500
5574
|
}, [visible]);
|
|
5501
|
-
(0,
|
|
5575
|
+
(0, import_react32.useEffect)(() => {
|
|
5502
5576
|
if (mutation.status === "success" && mutation.data) {
|
|
5503
5577
|
setShowCelebration(true);
|
|
5504
5578
|
import_react_native19.Animated.parallel([
|
|
@@ -5521,14 +5595,14 @@ function ClaimPrizeSheet({
|
|
|
5521
5595
|
return () => clearTimeout(timer);
|
|
5522
5596
|
}
|
|
5523
5597
|
}, [mutation.status, mutation.data]);
|
|
5524
|
-
(0,
|
|
5598
|
+
(0, import_react32.useEffect)(() => {
|
|
5525
5599
|
if (mutation.status === "error" && mutation.error) {
|
|
5526
5600
|
onError?.(mutation.error);
|
|
5527
5601
|
}
|
|
5528
5602
|
}, [mutation.status, mutation.error]);
|
|
5529
5603
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
5530
5604
|
const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
|
|
5531
|
-
const handleClaim = (0,
|
|
5605
|
+
const handleClaim = (0, import_react32.useCallback)(async () => {
|
|
5532
5606
|
if (!wallet.publicKey) return;
|
|
5533
5607
|
try {
|
|
5534
5608
|
await mutation.execute({
|
|
@@ -5761,7 +5835,7 @@ var styles13 = import_react_native19.StyleSheet.create({
|
|
|
5761
5835
|
});
|
|
5762
5836
|
|
|
5763
5837
|
// src/ui/game/ClaimButton.tsx
|
|
5764
|
-
var
|
|
5838
|
+
var import_react33 = require("react");
|
|
5765
5839
|
var import_react_native20 = require("react-native");
|
|
5766
5840
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5767
5841
|
function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
@@ -5769,9 +5843,9 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
|
5769
5843
|
const { wallet } = useDubs();
|
|
5770
5844
|
const game = useGame(gameId);
|
|
5771
5845
|
const claimStatus = useHasClaimed(gameId);
|
|
5772
|
-
const [sheetVisible, setSheetVisible] = (0,
|
|
5846
|
+
const [sheetVisible, setSheetVisible] = (0, import_react33.useState)(false);
|
|
5773
5847
|
const walletAddress = wallet.publicKey?.toBase58() ?? null;
|
|
5774
|
-
const myBet = (0,
|
|
5848
|
+
const myBet = (0, import_react33.useMemo)(() => {
|
|
5775
5849
|
if (!walletAddress || !game.data?.bettors) return null;
|
|
5776
5850
|
return game.data.bettors.find((b) => b.wallet === walletAddress) ?? null;
|
|
5777
5851
|
}, [walletAddress, game.data?.bettors]);
|
|
@@ -5780,7 +5854,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
|
5780
5854
|
const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
|
|
5781
5855
|
const isEligible = myBet != null && isResolved && (isWinner || isRefund);
|
|
5782
5856
|
const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
|
|
5783
|
-
const handleSuccess = (0,
|
|
5857
|
+
const handleSuccess = (0, import_react33.useCallback)(
|
|
5784
5858
|
(result) => {
|
|
5785
5859
|
claimStatus.refetch();
|
|
5786
5860
|
onSuccess?.(result);
|
|
@@ -5865,6 +5939,206 @@ var styles14 = import_react_native20.StyleSheet.create({
|
|
|
5865
5939
|
fontWeight: "700"
|
|
5866
5940
|
}
|
|
5867
5941
|
});
|
|
5942
|
+
|
|
5943
|
+
// src/ui/game/EnterArcadePoolSheet.tsx
|
|
5944
|
+
var import_react34 = require("react");
|
|
5945
|
+
var import_react_native21 = require("react-native");
|
|
5946
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5947
|
+
var STATUS_LABELS5 = {
|
|
5948
|
+
building: "Building transaction...",
|
|
5949
|
+
signing: "Approve in wallet...",
|
|
5950
|
+
confirming: "Confirming...",
|
|
5951
|
+
success: "Joined!"
|
|
5952
|
+
};
|
|
5953
|
+
function EnterArcadePoolSheet({
|
|
5954
|
+
visible,
|
|
5955
|
+
onDismiss,
|
|
5956
|
+
pool,
|
|
5957
|
+
stats,
|
|
5958
|
+
onSuccess,
|
|
5959
|
+
onError
|
|
5960
|
+
}) {
|
|
5961
|
+
const t = useDubsTheme();
|
|
5962
|
+
const { wallet } = useDubs();
|
|
5963
|
+
const mutation = useEnterArcadePool();
|
|
5964
|
+
const overlayOpacity = (0, import_react34.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
5965
|
+
(0, import_react34.useEffect)(() => {
|
|
5966
|
+
import_react_native21.Animated.timing(overlayOpacity, {
|
|
5967
|
+
toValue: visible ? 1 : 0,
|
|
5968
|
+
duration: 250,
|
|
5969
|
+
useNativeDriver: true
|
|
5970
|
+
}).start();
|
|
5971
|
+
}, [visible, overlayOpacity]);
|
|
5972
|
+
(0, import_react34.useEffect)(() => {
|
|
5973
|
+
if (visible) {
|
|
5974
|
+
mutation.reset();
|
|
5975
|
+
}
|
|
5976
|
+
}, [visible]);
|
|
5977
|
+
(0, import_react34.useEffect)(() => {
|
|
5978
|
+
if (mutation.status === "success" && mutation.data) {
|
|
5979
|
+
onSuccess?.(mutation.data);
|
|
5980
|
+
const timer = setTimeout(() => {
|
|
5981
|
+
onDismiss();
|
|
5982
|
+
}, 1500);
|
|
5983
|
+
return () => clearTimeout(timer);
|
|
5984
|
+
}
|
|
5985
|
+
}, [mutation.status, mutation.data]);
|
|
5986
|
+
(0, import_react34.useEffect)(() => {
|
|
5987
|
+
if (mutation.status === "error" && mutation.error) {
|
|
5988
|
+
onError?.(mutation.error);
|
|
5989
|
+
}
|
|
5990
|
+
}, [mutation.status, mutation.error]);
|
|
5991
|
+
const buyInSol = (pool.buy_in_lamports / 1e9).toFixed(4);
|
|
5992
|
+
const totalPlayers = stats?.total_entries ?? pool.total_entries ?? 0;
|
|
5993
|
+
const topScore = stats?.top_score ?? 0;
|
|
5994
|
+
const potSol = (pool.buy_in_lamports * Number(totalPlayers) / 1e9).toFixed(4);
|
|
5995
|
+
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
5996
|
+
const canJoin = !isMutating && mutation.status !== "success";
|
|
5997
|
+
const handleJoin = (0, import_react34.useCallback)(async () => {
|
|
5998
|
+
if (!wallet.publicKey) return;
|
|
5999
|
+
try {
|
|
6000
|
+
await mutation.execute(pool.id);
|
|
6001
|
+
} catch {
|
|
6002
|
+
}
|
|
6003
|
+
}, [wallet.publicKey, mutation.execute, pool.id]);
|
|
6004
|
+
const statusLabel = STATUS_LABELS5[mutation.status] || "";
|
|
6005
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
6006
|
+
import_react_native21.Modal,
|
|
6007
|
+
{
|
|
6008
|
+
visible,
|
|
6009
|
+
animationType: "slide",
|
|
6010
|
+
transparent: true,
|
|
6011
|
+
onRequestClose: onDismiss,
|
|
6012
|
+
children: [
|
|
6013
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Animated.View, { style: [styles15.overlay, { opacity: overlayOpacity }], children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.TouchableOpacity, { style: styles15.overlayTap, activeOpacity: 1, onPress: onDismiss }) }),
|
|
6014
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
6015
|
+
import_react_native21.KeyboardAvoidingView,
|
|
6016
|
+
{
|
|
6017
|
+
style: styles15.keyboardView,
|
|
6018
|
+
behavior: import_react_native21.Platform.OS === "ios" ? "padding" : void 0,
|
|
6019
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: styles15.sheetPositioner, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: [styles15.sheet, { backgroundColor: t.background }], children: [
|
|
6020
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: styles15.handleRow, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.handle, { backgroundColor: t.textMuted }] }) }),
|
|
6021
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.header, children: [
|
|
6022
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.headerTitle, { color: t.text }], children: "Join Pool" }),
|
|
6023
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.TouchableOpacity, { onPress: onDismiss, activeOpacity: 0.8, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.closeButton, { color: t.textMuted }], children: "\u2715" }) })
|
|
6024
|
+
] }),
|
|
6025
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.poolName, { color: t.textSecondary }], children: pool.name }),
|
|
6026
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: [styles15.summaryCard, { backgroundColor: t.surface, borderColor: t.border }], children: [
|
|
6027
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
|
|
6028
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Buy-in" }),
|
|
6029
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: [
|
|
6030
|
+
buyInSol,
|
|
6031
|
+
" SOL"
|
|
6032
|
+
] })
|
|
6033
|
+
] }),
|
|
6034
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
|
|
6035
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
|
|
6036
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Players in" }),
|
|
6037
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: totalPlayers })
|
|
6038
|
+
] }),
|
|
6039
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
|
|
6040
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
|
|
6041
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Current pot" }),
|
|
6042
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.success }], children: [
|
|
6043
|
+
potSol,
|
|
6044
|
+
" SOL"
|
|
6045
|
+
] })
|
|
6046
|
+
] }),
|
|
6047
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
|
|
6048
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Lives" }),
|
|
6050
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: pool.max_lives })
|
|
6051
|
+
] }),
|
|
6052
|
+
topScore > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
6053
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.summarySep, { backgroundColor: t.border }] }),
|
|
6054
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.summaryRow, children: [
|
|
6055
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryLabel, { color: t.textMuted }], children: "Top score" }),
|
|
6056
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.summaryValue, { color: t.text }], children: topScore })
|
|
6057
|
+
] })
|
|
6058
|
+
] })
|
|
6059
|
+
] }),
|
|
6060
|
+
mutation.error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: [styles15.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }], children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.errorText, { color: t.errorText }], children: mutation.error.message }) }),
|
|
6061
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
6062
|
+
import_react_native21.TouchableOpacity,
|
|
6063
|
+
{
|
|
6064
|
+
style: [
|
|
6065
|
+
styles15.ctaButton,
|
|
6066
|
+
{ backgroundColor: canJoin ? t.accent : t.border }
|
|
6067
|
+
],
|
|
6068
|
+
disabled: !canJoin,
|
|
6069
|
+
onPress: handleJoin,
|
|
6070
|
+
activeOpacity: 0.8,
|
|
6071
|
+
children: isMutating ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: styles15.ctaLoading, children: [
|
|
6072
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
|
|
6073
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: styles15.ctaText, children: statusLabel })
|
|
6074
|
+
] }) : mutation.status === "success" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: styles15.ctaText, children: "Joined!" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.Text, { style: [styles15.ctaText, !canJoin && { opacity: 0.5 }], children: `Join Pool \u2014 ${buyInSol} SOL` })
|
|
6075
|
+
}
|
|
6076
|
+
)
|
|
6077
|
+
] }) })
|
|
6078
|
+
}
|
|
6079
|
+
)
|
|
6080
|
+
]
|
|
6081
|
+
}
|
|
6082
|
+
);
|
|
6083
|
+
}
|
|
6084
|
+
var styles15 = import_react_native21.StyleSheet.create({
|
|
6085
|
+
overlay: {
|
|
6086
|
+
...import_react_native21.StyleSheet.absoluteFillObject,
|
|
6087
|
+
backgroundColor: "rgba(0,0,0,0.5)"
|
|
6088
|
+
},
|
|
6089
|
+
overlayTap: { flex: 1 },
|
|
6090
|
+
keyboardView: { flex: 1, justifyContent: "flex-end" },
|
|
6091
|
+
sheetPositioner: { justifyContent: "flex-end" },
|
|
6092
|
+
sheet: {
|
|
6093
|
+
borderTopLeftRadius: 24,
|
|
6094
|
+
borderTopRightRadius: 24,
|
|
6095
|
+
paddingHorizontal: 20,
|
|
6096
|
+
paddingBottom: 40
|
|
6097
|
+
},
|
|
6098
|
+
handleRow: { alignItems: "center", paddingTop: 10, paddingBottom: 8 },
|
|
6099
|
+
handle: { width: 36, height: 4, borderRadius: 2, opacity: 0.4 },
|
|
6100
|
+
header: {
|
|
6101
|
+
flexDirection: "row",
|
|
6102
|
+
alignItems: "center",
|
|
6103
|
+
justifyContent: "space-between",
|
|
6104
|
+
paddingVertical: 12
|
|
6105
|
+
},
|
|
6106
|
+
headerTitle: { fontSize: 20, fontWeight: "700" },
|
|
6107
|
+
closeButton: { fontSize: 20, padding: 4 },
|
|
6108
|
+
poolName: { fontSize: 15, fontWeight: "600", marginBottom: 8 },
|
|
6109
|
+
summaryCard: {
|
|
6110
|
+
marginTop: 12,
|
|
6111
|
+
borderRadius: 16,
|
|
6112
|
+
borderWidth: 1,
|
|
6113
|
+
overflow: "hidden"
|
|
6114
|
+
},
|
|
6115
|
+
summaryRow: {
|
|
6116
|
+
flexDirection: "row",
|
|
6117
|
+
alignItems: "center",
|
|
6118
|
+
justifyContent: "space-between",
|
|
6119
|
+
paddingHorizontal: 16,
|
|
6120
|
+
paddingVertical: 14
|
|
6121
|
+
},
|
|
6122
|
+
summaryLabel: { fontSize: 14 },
|
|
6123
|
+
summaryValue: { fontSize: 15, fontWeight: "700" },
|
|
6124
|
+
summarySep: { height: 1, marginHorizontal: 16 },
|
|
6125
|
+
errorBox: {
|
|
6126
|
+
marginTop: 16,
|
|
6127
|
+
borderRadius: 12,
|
|
6128
|
+
borderWidth: 1,
|
|
6129
|
+
padding: 12
|
|
6130
|
+
},
|
|
6131
|
+
errorText: { fontSize: 13, fontWeight: "500" },
|
|
6132
|
+
ctaButton: {
|
|
6133
|
+
marginTop: 20,
|
|
6134
|
+
height: 56,
|
|
6135
|
+
borderRadius: 14,
|
|
6136
|
+
justifyContent: "center",
|
|
6137
|
+
alignItems: "center"
|
|
6138
|
+
},
|
|
6139
|
+
ctaText: { color: "#FFFFFF", fontSize: 16, fontWeight: "700" },
|
|
6140
|
+
ctaLoading: { flexDirection: "row", alignItems: "center", gap: 10 }
|
|
6141
|
+
});
|
|
5868
6142
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5869
6143
|
0 && (module.exports = {
|
|
5870
6144
|
AuthGate,
|
|
@@ -5877,6 +6151,7 @@ var styles14 = import_react_native20.StyleSheet.create({
|
|
|
5877
6151
|
DubsApiError,
|
|
5878
6152
|
DubsClient,
|
|
5879
6153
|
DubsProvider,
|
|
6154
|
+
EnterArcadePoolSheet,
|
|
5880
6155
|
GamePoster,
|
|
5881
6156
|
JoinGameButton,
|
|
5882
6157
|
JoinGameSheet,
|
|
@@ -5908,6 +6183,7 @@ var styles14 = import_react_native20.StyleSheet.create({
|
|
|
5908
6183
|
useCreateGame,
|
|
5909
6184
|
useDubs,
|
|
5910
6185
|
useDubsTheme,
|
|
6186
|
+
useEnterArcadePool,
|
|
5911
6187
|
useEvents,
|
|
5912
6188
|
useGame,
|
|
5913
6189
|
useGames,
|