@dubsdotapp/expo 0.3.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +80 -2
- package/dist/index.d.ts +80 -2
- package/dist/index.js +255 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +233 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useArcadeBridge.ts +188 -0
- package/src/hooks/useArcadeCountdown.ts +71 -0
- package/src/index.ts +5 -0
- package/src/types.ts +2 -1
package/dist/index.mjs
CHANGED
|
@@ -636,7 +636,7 @@ function createSecureStoreStorage() {
|
|
|
636
636
|
}
|
|
637
637
|
|
|
638
638
|
// src/provider.tsx
|
|
639
|
-
import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useCallback as
|
|
639
|
+
import { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useCallback as useCallback20, useState as useState22, useEffect as useEffect14 } from "react";
|
|
640
640
|
|
|
641
641
|
// src/ui/theme.ts
|
|
642
642
|
import { createContext, useContext } from "react";
|
|
@@ -1701,7 +1701,7 @@ function ManagedWalletProvider({
|
|
|
1701
1701
|
}
|
|
1702
1702
|
|
|
1703
1703
|
// src/ui/AuthGate.tsx
|
|
1704
|
-
import React2, { useState as
|
|
1704
|
+
import React2, { useState as useState21, useEffect as useEffect13, useRef as useRef6, useCallback as useCallback19 } from "react";
|
|
1705
1705
|
import {
|
|
1706
1706
|
View as View3,
|
|
1707
1707
|
Text as Text3,
|
|
@@ -2736,6 +2736,135 @@ function useEnterArcadePool() {
|
|
|
2736
2736
|
return { execute, status, error, data, reset };
|
|
2737
2737
|
}
|
|
2738
2738
|
|
|
2739
|
+
// src/hooks/useArcadeCountdown.ts
|
|
2740
|
+
import { useState as useState19, useEffect as useEffect12, useRef as useRef4 } from "react";
|
|
2741
|
+
function formatCountdown(ms) {
|
|
2742
|
+
if (ms <= 0) return "Ended";
|
|
2743
|
+
const s2 = Math.floor(ms / 1e3);
|
|
2744
|
+
const m = Math.floor(s2 / 60);
|
|
2745
|
+
const h = Math.floor(m / 60);
|
|
2746
|
+
const d = Math.floor(h / 24);
|
|
2747
|
+
if (d > 0) return `${d}d ${h % 24}h ${m % 60}m`;
|
|
2748
|
+
if (h > 0) return `${h}h ${m % 60}m ${s2 % 60}s`;
|
|
2749
|
+
if (m > 0) return `${m}m ${s2 % 60}s`;
|
|
2750
|
+
return `${s2}s`;
|
|
2751
|
+
}
|
|
2752
|
+
function useArcadeCountdown(nextResolution) {
|
|
2753
|
+
const [now, setNow] = useState19(Date.now());
|
|
2754
|
+
const intervalRef = useRef4(null);
|
|
2755
|
+
useEffect12(() => {
|
|
2756
|
+
if (!nextResolution) return;
|
|
2757
|
+
intervalRef.current = setInterval(() => setNow(Date.now()), 1e3);
|
|
2758
|
+
return () => {
|
|
2759
|
+
if (intervalRef.current) clearInterval(intervalRef.current);
|
|
2760
|
+
};
|
|
2761
|
+
}, [nextResolution]);
|
|
2762
|
+
if (!nextResolution) {
|
|
2763
|
+
return { totalMs: 0, days: 0, hours: 0, minutes: 0, seconds: 0, formatted: "--", isExpired: false };
|
|
2764
|
+
}
|
|
2765
|
+
const target = new Date(nextResolution).getTime();
|
|
2766
|
+
const totalMs = Math.max(0, target - now);
|
|
2767
|
+
const totalSec = Math.floor(totalMs / 1e3);
|
|
2768
|
+
const days = Math.floor(totalSec / 86400);
|
|
2769
|
+
const hours = Math.floor(totalSec % 86400 / 3600);
|
|
2770
|
+
const minutes = Math.floor(totalSec % 3600 / 60);
|
|
2771
|
+
const seconds = totalSec % 60;
|
|
2772
|
+
return {
|
|
2773
|
+
totalMs,
|
|
2774
|
+
days,
|
|
2775
|
+
hours,
|
|
2776
|
+
minutes,
|
|
2777
|
+
seconds,
|
|
2778
|
+
formatted: formatCountdown(totalMs),
|
|
2779
|
+
isExpired: totalMs <= 0
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
// src/hooks/useArcadeBridge.ts
|
|
2784
|
+
import { useRef as useRef5, useState as useState20, useCallback as useCallback18 } from "react";
|
|
2785
|
+
var PROTOCOL_VERSION = "1.0";
|
|
2786
|
+
function useArcadeBridge({
|
|
2787
|
+
canPlay,
|
|
2788
|
+
startAttempt,
|
|
2789
|
+
submitScore,
|
|
2790
|
+
onScoreSubmitted,
|
|
2791
|
+
onError
|
|
2792
|
+
}) {
|
|
2793
|
+
const webviewRef = useRef5(null);
|
|
2794
|
+
const sessionTokenRef = useRef5(null);
|
|
2795
|
+
const gameStartTimeRef = useRef5(0);
|
|
2796
|
+
const [lastResult, setLastResult] = useState20(null);
|
|
2797
|
+
const [bridgeLoading, setBridgeLoading] = useState20(false);
|
|
2798
|
+
const injectSession = useCallback18((token, attemptNumber) => {
|
|
2799
|
+
webviewRef.current?.injectJavaScript(`
|
|
2800
|
+
window.ARCADE_SESSION_TOKEN = ${JSON.stringify(token)};
|
|
2801
|
+
window.ARCADE_ATTEMPT_NUMBER = ${attemptNumber};
|
|
2802
|
+
window._ARCADE_GAME_START_TIME = Date.now();
|
|
2803
|
+
window.dispatchEvent(new Event('ARCADE_START'));
|
|
2804
|
+
true;
|
|
2805
|
+
`);
|
|
2806
|
+
}, []);
|
|
2807
|
+
const triggerPlay = useCallback18(async () => {
|
|
2808
|
+
if (!canPlay) return;
|
|
2809
|
+
setBridgeLoading(true);
|
|
2810
|
+
try {
|
|
2811
|
+
const result = await startAttempt();
|
|
2812
|
+
sessionTokenRef.current = result.sessionToken;
|
|
2813
|
+
gameStartTimeRef.current = Date.now();
|
|
2814
|
+
setLastResult(null);
|
|
2815
|
+
injectSession(result.sessionToken, result.attemptNumber);
|
|
2816
|
+
} catch (err) {
|
|
2817
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
2818
|
+
onError?.(e);
|
|
2819
|
+
} finally {
|
|
2820
|
+
setBridgeLoading(false);
|
|
2821
|
+
}
|
|
2822
|
+
}, [canPlay, startAttempt, injectSession, onError]);
|
|
2823
|
+
const handleMessage = useCallback18(
|
|
2824
|
+
async (event) => {
|
|
2825
|
+
let data;
|
|
2826
|
+
try {
|
|
2827
|
+
data = JSON.parse(event.nativeEvent.data);
|
|
2828
|
+
} catch {
|
|
2829
|
+
return;
|
|
2830
|
+
}
|
|
2831
|
+
if (data.dubsArcade !== PROTOCOL_VERSION) return;
|
|
2832
|
+
switch (data.type) {
|
|
2833
|
+
case "TAP_PLAY": {
|
|
2834
|
+
if (canPlay) {
|
|
2835
|
+
triggerPlay();
|
|
2836
|
+
}
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
case "GAME_OVER": {
|
|
2840
|
+
const token = sessionTokenRef.current;
|
|
2841
|
+
if (!token) return;
|
|
2842
|
+
const score = typeof data.score === "number" ? data.score : 0;
|
|
2843
|
+
const duration = gameStartTimeRef.current > 0 ? Date.now() - gameStartTimeRef.current : typeof data.durationMs === "number" ? data.durationMs : void 0;
|
|
2844
|
+
sessionTokenRef.current = null;
|
|
2845
|
+
gameStartTimeRef.current = 0;
|
|
2846
|
+
setBridgeLoading(true);
|
|
2847
|
+
try {
|
|
2848
|
+
const result = await submitScore(token, score, duration);
|
|
2849
|
+
setLastResult(result);
|
|
2850
|
+
onScoreSubmitted?.(result);
|
|
2851
|
+
} catch (err) {
|
|
2852
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
2853
|
+
onError?.(e);
|
|
2854
|
+
} finally {
|
|
2855
|
+
setBridgeLoading(false);
|
|
2856
|
+
}
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
default:
|
|
2860
|
+
return;
|
|
2861
|
+
}
|
|
2862
|
+
},
|
|
2863
|
+
[canPlay, triggerPlay, submitScore, onScoreSubmitted, onError]
|
|
2864
|
+
);
|
|
2865
|
+
return { webviewRef, handleMessage, triggerPlay, lastResult, bridgeLoading };
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2739
2868
|
// src/ui/AvatarEditor.tsx
|
|
2740
2869
|
import {
|
|
2741
2870
|
View as View2,
|
|
@@ -2903,11 +3032,11 @@ function AuthGate({
|
|
|
2903
3032
|
}) {
|
|
2904
3033
|
const { client, pushEnabled } = useDubs();
|
|
2905
3034
|
const auth = useAuth();
|
|
2906
|
-
const [phase, setPhase] =
|
|
2907
|
-
const [registrationPhase, setRegistrationPhase] =
|
|
2908
|
-
const [showPushSetup, setShowPushSetup] =
|
|
2909
|
-
const [isRestoredSession, setIsRestoredSession] =
|
|
2910
|
-
|
|
3035
|
+
const [phase, setPhase] = useState21("init");
|
|
3036
|
+
const [registrationPhase, setRegistrationPhase] = useState21(false);
|
|
3037
|
+
const [showPushSetup, setShowPushSetup] = useState21(false);
|
|
3038
|
+
const [isRestoredSession, setIsRestoredSession] = useState21(false);
|
|
3039
|
+
useEffect13(() => {
|
|
2911
3040
|
let cancelled = false;
|
|
2912
3041
|
(async () => {
|
|
2913
3042
|
try {
|
|
@@ -2934,23 +3063,23 @@ function AuthGate({
|
|
|
2934
3063
|
cancelled = true;
|
|
2935
3064
|
};
|
|
2936
3065
|
}, []);
|
|
2937
|
-
|
|
3066
|
+
useEffect13(() => {
|
|
2938
3067
|
if (auth.status === "needsRegistration") setRegistrationPhase(true);
|
|
2939
3068
|
}, [auth.status]);
|
|
2940
|
-
|
|
3069
|
+
useEffect13(() => {
|
|
2941
3070
|
if (pushEnabled && auth.status === "authenticated" && registrationPhase && !isRestoredSession) {
|
|
2942
3071
|
setShowPushSetup(true);
|
|
2943
3072
|
}
|
|
2944
3073
|
}, [pushEnabled, auth.status, registrationPhase, isRestoredSession]);
|
|
2945
|
-
|
|
3074
|
+
useEffect13(() => {
|
|
2946
3075
|
if (auth.token) onSaveToken(auth.token);
|
|
2947
3076
|
}, [auth.token]);
|
|
2948
|
-
const retry =
|
|
3077
|
+
const retry = useCallback19(() => {
|
|
2949
3078
|
setRegistrationPhase(false);
|
|
2950
3079
|
auth.reset();
|
|
2951
3080
|
auth.authenticate();
|
|
2952
3081
|
}, [auth]);
|
|
2953
|
-
const handleRegister =
|
|
3082
|
+
const handleRegister = useCallback19(
|
|
2954
3083
|
(username, referralCode, avatarUrl) => {
|
|
2955
3084
|
auth.register(username, referralCode, avatarUrl);
|
|
2956
3085
|
},
|
|
@@ -3066,20 +3195,20 @@ function DefaultRegistrationScreen({
|
|
|
3066
3195
|
}) {
|
|
3067
3196
|
const t = useDubsTheme();
|
|
3068
3197
|
const accent = accentColor || t.accent;
|
|
3069
|
-
const [step, setStep] =
|
|
3070
|
-
const [avatarSeed, setAvatarSeed] =
|
|
3071
|
-
const [avatarStyle, setAvatarStyle] =
|
|
3072
|
-
const [avatarBg, setAvatarBg] =
|
|
3073
|
-
const [showStyles, setShowStyles] =
|
|
3074
|
-
const [username, setUsername] =
|
|
3075
|
-
const [referralCode, setReferralCode] =
|
|
3076
|
-
const [checking, setChecking] =
|
|
3077
|
-
const [availability, setAvailability] =
|
|
3078
|
-
const debounceRef =
|
|
3079
|
-
const fadeAnim =
|
|
3080
|
-
const slideAnim =
|
|
3198
|
+
const [step, setStep] = useState21(0);
|
|
3199
|
+
const [avatarSeed, setAvatarSeed] = useState21(generateSeed);
|
|
3200
|
+
const [avatarStyle, setAvatarStyle] = useState21("adventurer");
|
|
3201
|
+
const [avatarBg, setAvatarBg] = useState21("1a1a2e");
|
|
3202
|
+
const [showStyles, setShowStyles] = useState21(false);
|
|
3203
|
+
const [username, setUsername] = useState21("");
|
|
3204
|
+
const [referralCode, setReferralCode] = useState21("");
|
|
3205
|
+
const [checking, setChecking] = useState21(false);
|
|
3206
|
+
const [availability, setAvailability] = useState21(null);
|
|
3207
|
+
const debounceRef = useRef6(null);
|
|
3208
|
+
const fadeAnim = useRef6(new Animated.Value(1)).current;
|
|
3209
|
+
const slideAnim = useRef6(new Animated.Value(0)).current;
|
|
3081
3210
|
const avatarUrl = getAvatarUrl(avatarStyle, avatarSeed, avatarBg);
|
|
3082
|
-
|
|
3211
|
+
useEffect13(() => {
|
|
3083
3212
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
3084
3213
|
const trimmed = username.trim();
|
|
3085
3214
|
if (trimmed.length < 3) {
|
|
@@ -3102,7 +3231,7 @@ function DefaultRegistrationScreen({
|
|
|
3102
3231
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
3103
3232
|
};
|
|
3104
3233
|
}, [username, client]);
|
|
3105
|
-
const animateToStep =
|
|
3234
|
+
const animateToStep = useCallback19((newStep) => {
|
|
3106
3235
|
const dir = newStep > step ? 1 : -1;
|
|
3107
3236
|
Keyboard.dismiss();
|
|
3108
3237
|
Animated.parallel([
|
|
@@ -3341,8 +3470,8 @@ function DefaultRegistrationScreen({
|
|
|
3341
3470
|
}
|
|
3342
3471
|
function PushTokenRestorer() {
|
|
3343
3472
|
const push = usePushNotifications();
|
|
3344
|
-
const restored =
|
|
3345
|
-
|
|
3473
|
+
const restored = useRef6(false);
|
|
3474
|
+
useEffect13(() => {
|
|
3346
3475
|
if (restored.current) return;
|
|
3347
3476
|
restored.current = true;
|
|
3348
3477
|
push.restoreIfGranted();
|
|
@@ -3357,9 +3486,9 @@ function PushSetupScreen({
|
|
|
3357
3486
|
const t = useDubsTheme();
|
|
3358
3487
|
const accent = accentColor || t.accent;
|
|
3359
3488
|
const push = usePushNotifications();
|
|
3360
|
-
const fadeAnim =
|
|
3361
|
-
const slideAnim =
|
|
3362
|
-
|
|
3489
|
+
const fadeAnim = useRef6(new Animated.Value(0)).current;
|
|
3490
|
+
const slideAnim = useRef6(new Animated.Value(30)).current;
|
|
3491
|
+
useEffect13(() => {
|
|
3363
3492
|
Animated.parallel([
|
|
3364
3493
|
Animated.timing(fadeAnim, { toValue: 1, duration: 300, useNativeDriver: true }),
|
|
3365
3494
|
Animated.timing(slideAnim, { toValue: 0, duration: 300, useNativeDriver: true })
|
|
@@ -3519,9 +3648,9 @@ function DubsProvider({
|
|
|
3519
3648
|
const rpcUrl = rpcUrlOverride || config.rpcUrl;
|
|
3520
3649
|
const client = useMemo3(() => new DubsClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
|
|
3521
3650
|
const storage = useMemo3(() => tokenStorage || createSecureStoreStorage(), [tokenStorage]);
|
|
3522
|
-
const [uiConfig, setUiConfig] =
|
|
3523
|
-
const [resolvedNetwork, setResolvedNetwork] =
|
|
3524
|
-
|
|
3651
|
+
const [uiConfig, setUiConfig] = useState22(null);
|
|
3652
|
+
const [resolvedNetwork, setResolvedNetwork] = useState22(network);
|
|
3653
|
+
useEffect14(() => {
|
|
3525
3654
|
client.getAppConfig().then((cfg) => {
|
|
3526
3655
|
console.log("[DubsProvider] UI config loaded:", JSON.stringify(cfg));
|
|
3527
3656
|
setUiConfig(cfg);
|
|
@@ -3613,7 +3742,7 @@ function ManagedInner({
|
|
|
3613
3742
|
children
|
|
3614
3743
|
}) {
|
|
3615
3744
|
const managedDisconnect = useDisconnect();
|
|
3616
|
-
const disconnect =
|
|
3745
|
+
const disconnect = useCallback20(async () => {
|
|
3617
3746
|
client.setToken(null);
|
|
3618
3747
|
await managedDisconnect?.();
|
|
3619
3748
|
}, [client, managedDisconnect]);
|
|
@@ -3654,7 +3783,7 @@ function ExternalWalletProvider({
|
|
|
3654
3783
|
pushEnabled,
|
|
3655
3784
|
children
|
|
3656
3785
|
}) {
|
|
3657
|
-
const disconnect =
|
|
3786
|
+
const disconnect = useCallback20(async () => {
|
|
3658
3787
|
client.setToken(null);
|
|
3659
3788
|
await storage.deleteItem(STORAGE_KEYS.JWT_TOKEN).catch(() => {
|
|
3660
3789
|
});
|
|
@@ -3917,7 +4046,7 @@ var styles4 = StyleSheet5.create({
|
|
|
3917
4046
|
});
|
|
3918
4047
|
|
|
3919
4048
|
// src/ui/UserProfileSheet.tsx
|
|
3920
|
-
import { useState as
|
|
4049
|
+
import { useState as useState23, useEffect as useEffect15, useRef as useRef7, useCallback as useCallback21, useMemo as useMemo5 } from "react";
|
|
3921
4050
|
import {
|
|
3922
4051
|
View as View6,
|
|
3923
4052
|
Text as Text6,
|
|
@@ -3948,31 +4077,31 @@ function UserProfileSheet({
|
|
|
3948
4077
|
const { client } = useDubs();
|
|
3949
4078
|
const { refreshUser } = useAuth();
|
|
3950
4079
|
const push = usePushNotifications();
|
|
3951
|
-
const overlayOpacity =
|
|
4080
|
+
const overlayOpacity = useRef7(new Animated2.Value(0)).current;
|
|
3952
4081
|
const parsed = useMemo5(() => parseAvatarUrl(user.avatar), [user.avatar]);
|
|
3953
|
-
const [avatarStyle, setAvatarStyle] =
|
|
3954
|
-
const [avatarSeed, setAvatarSeed] =
|
|
3955
|
-
const [bgColor, setBgColor] =
|
|
3956
|
-
const [saving, setSaving] =
|
|
3957
|
-
const [error, setError] =
|
|
3958
|
-
|
|
4082
|
+
const [avatarStyle, setAvatarStyle] = useState23(parsed.style);
|
|
4083
|
+
const [avatarSeed, setAvatarSeed] = useState23(parsed.seed);
|
|
4084
|
+
const [bgColor, setBgColor] = useState23(parsed.bg);
|
|
4085
|
+
const [saving, setSaving] = useState23(false);
|
|
4086
|
+
const [error, setError] = useState23(null);
|
|
4087
|
+
useEffect15(() => {
|
|
3959
4088
|
const p = parseAvatarUrl(user.avatar);
|
|
3960
4089
|
setAvatarStyle(p.style);
|
|
3961
4090
|
setAvatarSeed(p.seed);
|
|
3962
4091
|
setBgColor(p.bg);
|
|
3963
4092
|
}, [user.avatar]);
|
|
3964
|
-
|
|
4093
|
+
useEffect15(() => {
|
|
3965
4094
|
Animated2.timing(overlayOpacity, {
|
|
3966
4095
|
toValue: visible ? 1 : 0,
|
|
3967
4096
|
duration: 250,
|
|
3968
4097
|
useNativeDriver: true
|
|
3969
4098
|
}).start();
|
|
3970
4099
|
}, [visible, overlayOpacity]);
|
|
3971
|
-
|
|
4100
|
+
useEffect15(() => {
|
|
3972
4101
|
if (visible) setError(null);
|
|
3973
4102
|
}, [visible]);
|
|
3974
4103
|
const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);
|
|
3975
|
-
const saveAvatar =
|
|
4104
|
+
const saveAvatar = useCallback21(async (newUrl) => {
|
|
3976
4105
|
setSaving(true);
|
|
3977
4106
|
setError(null);
|
|
3978
4107
|
try {
|
|
@@ -3985,16 +4114,16 @@ function UserProfileSheet({
|
|
|
3985
4114
|
setSaving(false);
|
|
3986
4115
|
}
|
|
3987
4116
|
}, [client, refreshUser, onAvatarUpdated]);
|
|
3988
|
-
const handleStyleChange =
|
|
4117
|
+
const handleStyleChange = useCallback21((style) => {
|
|
3989
4118
|
setAvatarStyle(style);
|
|
3990
4119
|
saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
|
|
3991
4120
|
}, [avatarSeed, bgColor, saveAvatar]);
|
|
3992
|
-
const handleShuffle =
|
|
4121
|
+
const handleShuffle = useCallback21(() => {
|
|
3993
4122
|
const newSeed = generateSeed();
|
|
3994
4123
|
setAvatarSeed(newSeed);
|
|
3995
4124
|
saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
|
|
3996
4125
|
}, [avatarStyle, bgColor, saveAvatar]);
|
|
3997
|
-
const handleBgChange =
|
|
4126
|
+
const handleBgChange = useCallback21((color) => {
|
|
3998
4127
|
setBgColor(color);
|
|
3999
4128
|
saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
|
|
4000
4129
|
}, [avatarStyle, avatarSeed, saveAvatar]);
|
|
@@ -4274,7 +4403,7 @@ var styles5 = StyleSheet6.create({
|
|
|
4274
4403
|
});
|
|
4275
4404
|
|
|
4276
4405
|
// src/ui/game/GamePoster.tsx
|
|
4277
|
-
import { useState as
|
|
4406
|
+
import { useState as useState24 } from "react";
|
|
4278
4407
|
import { StyleSheet as StyleSheet7, View as View7, Text as Text7 } from "react-native";
|
|
4279
4408
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4280
4409
|
function computeCountdown(lockTimestamp) {
|
|
@@ -4324,7 +4453,7 @@ function GamePoster({ game, ImageComponent }) {
|
|
|
4324
4453
|
] });
|
|
4325
4454
|
}
|
|
4326
4455
|
function TeamLogoInternal({ url, size, Img }) {
|
|
4327
|
-
const [failed, setFailed] =
|
|
4456
|
+
const [failed, setFailed] = useState24(false);
|
|
4328
4457
|
if (!url || failed) {
|
|
4329
4458
|
return /* @__PURE__ */ jsx9(View7, { style: [styles6.logoPlaceholder, { width: size, height: size, borderRadius: size / 2 }] });
|
|
4330
4459
|
}
|
|
@@ -4504,7 +4633,7 @@ var styles7 = StyleSheet8.create({
|
|
|
4504
4633
|
});
|
|
4505
4634
|
|
|
4506
4635
|
// src/ui/game/PickWinnerCard.tsx
|
|
4507
|
-
import { useState as
|
|
4636
|
+
import { useState as useState25, useMemo as useMemo7 } from "react";
|
|
4508
4637
|
import { StyleSheet as StyleSheet9, View as View9, Text as Text9, TouchableOpacity as TouchableOpacity6 } from "react-native";
|
|
4509
4638
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4510
4639
|
function PickWinnerCard({
|
|
@@ -4575,7 +4704,7 @@ function TeamOption({
|
|
|
4575
4704
|
ImageComponent,
|
|
4576
4705
|
t
|
|
4577
4706
|
}) {
|
|
4578
|
-
const [imgFailed, setImgFailed] =
|
|
4707
|
+
const [imgFailed, setImgFailed] = useState25(false);
|
|
4579
4708
|
const Img = ImageComponent || __require("react-native").Image;
|
|
4580
4709
|
const showImage = imageUrl && !imgFailed;
|
|
4581
4710
|
return /* @__PURE__ */ jsxs9(
|
|
@@ -4616,7 +4745,7 @@ var styles8 = StyleSheet9.create({
|
|
|
4616
4745
|
});
|
|
4617
4746
|
|
|
4618
4747
|
// src/ui/game/PlayersCard.tsx
|
|
4619
|
-
import { useState as
|
|
4748
|
+
import { useState as useState26 } from "react";
|
|
4620
4749
|
import { StyleSheet as StyleSheet10, View as View10, Text as Text10 } from "react-native";
|
|
4621
4750
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4622
4751
|
function truncateWallet(addr, chars) {
|
|
@@ -4665,7 +4794,7 @@ function BettorRow({
|
|
|
4665
4794
|
ImageComponent,
|
|
4666
4795
|
t
|
|
4667
4796
|
}) {
|
|
4668
|
-
const [imgFailed, setImgFailed] =
|
|
4797
|
+
const [imgFailed, setImgFailed] = useState26(false);
|
|
4669
4798
|
const Img = ImageComponent || __require("react-native").Image;
|
|
4670
4799
|
const showAvatar = bettor.avatar && !imgFailed;
|
|
4671
4800
|
return /* @__PURE__ */ jsxs10(View10, { style: [styles9.row, !isFirst && { borderTopColor: t.border, borderTopWidth: 1 }], children: [
|
|
@@ -4744,7 +4873,7 @@ var styles10 = StyleSheet11.create({
|
|
|
4744
4873
|
});
|
|
4745
4874
|
|
|
4746
4875
|
// src/ui/game/CreateCustomGameSheet.tsx
|
|
4747
|
-
import { useState as
|
|
4876
|
+
import { useState as useState27, useEffect as useEffect16, useRef as useRef8, useCallback as useCallback22 } from "react";
|
|
4748
4877
|
import {
|
|
4749
4878
|
View as View12,
|
|
4750
4879
|
Text as Text12,
|
|
@@ -4781,18 +4910,18 @@ function CreateCustomGameSheet({
|
|
|
4781
4910
|
const t = useDubsTheme();
|
|
4782
4911
|
const { wallet } = useDubs();
|
|
4783
4912
|
const mutation = useCreateCustomGame();
|
|
4784
|
-
const [selectedAmount, setSelectedAmount] =
|
|
4785
|
-
const [customAmount, setCustomAmount] =
|
|
4786
|
-
const [isCustom, setIsCustom] =
|
|
4787
|
-
const overlayOpacity =
|
|
4788
|
-
|
|
4913
|
+
const [selectedAmount, setSelectedAmount] = useState27(null);
|
|
4914
|
+
const [customAmount, setCustomAmount] = useState27("");
|
|
4915
|
+
const [isCustom, setIsCustom] = useState27(false);
|
|
4916
|
+
const overlayOpacity = useRef8(new Animated3.Value(0)).current;
|
|
4917
|
+
useEffect16(() => {
|
|
4789
4918
|
Animated3.timing(overlayOpacity, {
|
|
4790
4919
|
toValue: visible ? 1 : 0,
|
|
4791
4920
|
duration: 250,
|
|
4792
4921
|
useNativeDriver: true
|
|
4793
4922
|
}).start();
|
|
4794
4923
|
}, [visible, overlayOpacity]);
|
|
4795
|
-
|
|
4924
|
+
useEffect16(() => {
|
|
4796
4925
|
if (visible) {
|
|
4797
4926
|
setSelectedAmount(defaultAmount ?? null);
|
|
4798
4927
|
setCustomAmount("");
|
|
@@ -4800,7 +4929,7 @@ function CreateCustomGameSheet({
|
|
|
4800
4929
|
mutation.reset();
|
|
4801
4930
|
}
|
|
4802
4931
|
}, [visible]);
|
|
4803
|
-
|
|
4932
|
+
useEffect16(() => {
|
|
4804
4933
|
if (mutation.status === "success" && mutation.data) {
|
|
4805
4934
|
onSuccess?.(mutation.data);
|
|
4806
4935
|
const timer = setTimeout(() => {
|
|
@@ -4809,23 +4938,23 @@ function CreateCustomGameSheet({
|
|
|
4809
4938
|
return () => clearTimeout(timer);
|
|
4810
4939
|
}
|
|
4811
4940
|
}, [mutation.status, mutation.data]);
|
|
4812
|
-
|
|
4941
|
+
useEffect16(() => {
|
|
4813
4942
|
if (mutation.status === "error" && mutation.error) {
|
|
4814
4943
|
onError?.(mutation.error);
|
|
4815
4944
|
}
|
|
4816
4945
|
}, [mutation.status, mutation.error]);
|
|
4817
|
-
const handlePresetSelect =
|
|
4946
|
+
const handlePresetSelect = useCallback22((amount) => {
|
|
4818
4947
|
setSelectedAmount(amount);
|
|
4819
4948
|
setIsCustom(false);
|
|
4820
4949
|
setCustomAmount("");
|
|
4821
4950
|
onAmountChange?.(amount);
|
|
4822
4951
|
}, [onAmountChange]);
|
|
4823
|
-
const handleCustomSelect =
|
|
4952
|
+
const handleCustomSelect = useCallback22(() => {
|
|
4824
4953
|
setIsCustom(true);
|
|
4825
4954
|
setSelectedAmount(null);
|
|
4826
4955
|
onAmountChange?.(null);
|
|
4827
4956
|
}, [onAmountChange]);
|
|
4828
|
-
const handleCustomAmountChange =
|
|
4957
|
+
const handleCustomAmountChange = useCallback22((text) => {
|
|
4829
4958
|
const cleaned = text.replace(/[^0-9.]/g, "").replace(/(\..*?)\..*/g, "$1");
|
|
4830
4959
|
setCustomAmount(cleaned);
|
|
4831
4960
|
const parsed = parseFloat(cleaned);
|
|
@@ -4840,7 +4969,7 @@ function CreateCustomGameSheet({
|
|
|
4840
4969
|
const winnerTakes = pot * (1 - fee / 100);
|
|
4841
4970
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
4842
4971
|
const canCreate = finalAmount !== null && finalAmount > 0 && !isMutating && mutation.status !== "success";
|
|
4843
|
-
const handleCreate =
|
|
4972
|
+
const handleCreate = useCallback22(async () => {
|
|
4844
4973
|
if (!finalAmount || !wallet.publicKey) return;
|
|
4845
4974
|
try {
|
|
4846
4975
|
await mutation.execute({
|
|
@@ -5109,7 +5238,7 @@ var styles11 = StyleSheet12.create({
|
|
|
5109
5238
|
});
|
|
5110
5239
|
|
|
5111
5240
|
// src/ui/game/JoinGameSheet.tsx
|
|
5112
|
-
import { useState as
|
|
5241
|
+
import { useState as useState28, useEffect as useEffect17, useRef as useRef9, useCallback as useCallback23, useMemo as useMemo9 } from "react";
|
|
5113
5242
|
import {
|
|
5114
5243
|
View as View13,
|
|
5115
5244
|
Text as Text13,
|
|
@@ -5145,22 +5274,22 @@ function JoinGameSheet({
|
|
|
5145
5274
|
const { wallet } = useDubs();
|
|
5146
5275
|
const mutation = useJoinGame();
|
|
5147
5276
|
const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
|
|
5148
|
-
const [selectedTeam, setSelectedTeam] =
|
|
5149
|
-
const overlayOpacity =
|
|
5150
|
-
|
|
5277
|
+
const [selectedTeam, setSelectedTeam] = useState28(null);
|
|
5278
|
+
const overlayOpacity = useRef9(new Animated4.Value(0)).current;
|
|
5279
|
+
useEffect17(() => {
|
|
5151
5280
|
Animated4.timing(overlayOpacity, {
|
|
5152
5281
|
toValue: visible ? 1 : 0,
|
|
5153
5282
|
duration: 250,
|
|
5154
5283
|
useNativeDriver: true
|
|
5155
5284
|
}).start();
|
|
5156
5285
|
}, [visible, overlayOpacity]);
|
|
5157
|
-
|
|
5286
|
+
useEffect17(() => {
|
|
5158
5287
|
if (visible) {
|
|
5159
5288
|
setSelectedTeam(isPoolModeEnabled ? "home" : isCustomGame ? "away" : null);
|
|
5160
5289
|
mutation.reset();
|
|
5161
5290
|
}
|
|
5162
5291
|
}, [visible]);
|
|
5163
|
-
|
|
5292
|
+
useEffect17(() => {
|
|
5164
5293
|
if (mutation.status === "success" && mutation.data) {
|
|
5165
5294
|
onSuccess?.(mutation.data);
|
|
5166
5295
|
const timer = setTimeout(() => {
|
|
@@ -5169,7 +5298,7 @@ function JoinGameSheet({
|
|
|
5169
5298
|
return () => clearTimeout(timer);
|
|
5170
5299
|
}
|
|
5171
5300
|
}, [mutation.status, mutation.data]);
|
|
5172
|
-
|
|
5301
|
+
useEffect17(() => {
|
|
5173
5302
|
if (mutation.status === "error" && mutation.error) {
|
|
5174
5303
|
onError?.(mutation.error);
|
|
5175
5304
|
}
|
|
@@ -5199,7 +5328,7 @@ function JoinGameSheet({
|
|
|
5199
5328
|
}, [bettors, wallet.publicKey]);
|
|
5200
5329
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
5201
5330
|
const canJoin = selectedTeam !== null && !isMutating && mutation.status !== "success" && !alreadyJoined;
|
|
5202
|
-
const handleJoin =
|
|
5331
|
+
const handleJoin = useCallback23(async () => {
|
|
5203
5332
|
if (!selectedTeam || !wallet.publicKey) return;
|
|
5204
5333
|
try {
|
|
5205
5334
|
await mutation.execute({
|
|
@@ -5343,7 +5472,7 @@ function TeamButton({
|
|
|
5343
5472
|
ImageComponent,
|
|
5344
5473
|
t
|
|
5345
5474
|
}) {
|
|
5346
|
-
const [imgFailed, setImgFailed] =
|
|
5475
|
+
const [imgFailed, setImgFailed] = useState28(false);
|
|
5347
5476
|
const Img = ImageComponent || __require("react-native").Image;
|
|
5348
5477
|
const showImage = imageUrl && !imgFailed;
|
|
5349
5478
|
return /* @__PURE__ */ jsxs13(
|
|
@@ -5520,7 +5649,7 @@ var styles12 = StyleSheet13.create({
|
|
|
5520
5649
|
});
|
|
5521
5650
|
|
|
5522
5651
|
// src/ui/game/ClaimPrizeSheet.tsx
|
|
5523
|
-
import { useState as
|
|
5652
|
+
import { useState as useState29, useEffect as useEffect18, useRef as useRef10, useCallback as useCallback24 } from "react";
|
|
5524
5653
|
import {
|
|
5525
5654
|
View as View14,
|
|
5526
5655
|
Text as Text14,
|
|
@@ -5551,18 +5680,18 @@ function ClaimPrizeSheet({
|
|
|
5551
5680
|
const t = useDubsTheme();
|
|
5552
5681
|
const { wallet } = useDubs();
|
|
5553
5682
|
const mutation = useClaim();
|
|
5554
|
-
const overlayOpacity =
|
|
5555
|
-
const celebrationScale =
|
|
5556
|
-
const celebrationOpacity =
|
|
5557
|
-
const [showCelebration, setShowCelebration] =
|
|
5558
|
-
|
|
5683
|
+
const overlayOpacity = useRef10(new Animated5.Value(0)).current;
|
|
5684
|
+
const celebrationScale = useRef10(new Animated5.Value(0)).current;
|
|
5685
|
+
const celebrationOpacity = useRef10(new Animated5.Value(0)).current;
|
|
5686
|
+
const [showCelebration, setShowCelebration] = useState29(false);
|
|
5687
|
+
useEffect18(() => {
|
|
5559
5688
|
Animated5.timing(overlayOpacity, {
|
|
5560
5689
|
toValue: visible ? 1 : 0,
|
|
5561
5690
|
duration: 250,
|
|
5562
5691
|
useNativeDriver: true
|
|
5563
5692
|
}).start();
|
|
5564
5693
|
}, [visible, overlayOpacity]);
|
|
5565
|
-
|
|
5694
|
+
useEffect18(() => {
|
|
5566
5695
|
if (visible) {
|
|
5567
5696
|
mutation.reset();
|
|
5568
5697
|
setShowCelebration(false);
|
|
@@ -5570,7 +5699,7 @@ function ClaimPrizeSheet({
|
|
|
5570
5699
|
celebrationOpacity.setValue(0);
|
|
5571
5700
|
}
|
|
5572
5701
|
}, [visible]);
|
|
5573
|
-
|
|
5702
|
+
useEffect18(() => {
|
|
5574
5703
|
if (mutation.status === "success" && mutation.data) {
|
|
5575
5704
|
setShowCelebration(true);
|
|
5576
5705
|
Animated5.parallel([
|
|
@@ -5593,14 +5722,14 @@ function ClaimPrizeSheet({
|
|
|
5593
5722
|
return () => clearTimeout(timer);
|
|
5594
5723
|
}
|
|
5595
5724
|
}, [mutation.status, mutation.data]);
|
|
5596
|
-
|
|
5725
|
+
useEffect18(() => {
|
|
5597
5726
|
if (mutation.status === "error" && mutation.error) {
|
|
5598
5727
|
onError?.(mutation.error);
|
|
5599
5728
|
}
|
|
5600
5729
|
}, [mutation.status, mutation.error]);
|
|
5601
5730
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
5602
5731
|
const canClaim = !isMutating && mutation.status !== "success" && !!wallet.publicKey;
|
|
5603
|
-
const handleClaim =
|
|
5732
|
+
const handleClaim = useCallback24(async () => {
|
|
5604
5733
|
if (!wallet.publicKey) return;
|
|
5605
5734
|
try {
|
|
5606
5735
|
await mutation.execute({
|
|
@@ -5833,7 +5962,7 @@ var styles13 = StyleSheet14.create({
|
|
|
5833
5962
|
});
|
|
5834
5963
|
|
|
5835
5964
|
// src/ui/game/ClaimButton.tsx
|
|
5836
|
-
import { useState as
|
|
5965
|
+
import { useState as useState30, useMemo as useMemo10, useCallback as useCallback25 } from "react";
|
|
5837
5966
|
import { StyleSheet as StyleSheet15, Text as Text15, TouchableOpacity as TouchableOpacity11 } from "react-native";
|
|
5838
5967
|
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5839
5968
|
function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
@@ -5841,7 +5970,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
|
5841
5970
|
const { wallet } = useDubs();
|
|
5842
5971
|
const game = useGame(gameId);
|
|
5843
5972
|
const claimStatus = useHasClaimed(gameId);
|
|
5844
|
-
const [sheetVisible, setSheetVisible] =
|
|
5973
|
+
const [sheetVisible, setSheetVisible] = useState30(false);
|
|
5845
5974
|
const walletAddress = wallet.publicKey?.toBase58() ?? null;
|
|
5846
5975
|
const myBet = useMemo10(() => {
|
|
5847
5976
|
if (!walletAddress || !game.data?.bettors) return null;
|
|
@@ -5852,7 +5981,7 @@ function ClaimButton({ gameId, style, onSuccess, onError }) {
|
|
|
5852
5981
|
const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
|
|
5853
5982
|
const isEligible = myBet != null && isResolved && (isWinner || isRefund);
|
|
5854
5983
|
const prizeAmount = isRefund ? myBet?.amount ?? 0 : game.data?.totalPool ?? 0;
|
|
5855
|
-
const handleSuccess =
|
|
5984
|
+
const handleSuccess = useCallback25(
|
|
5856
5985
|
(result) => {
|
|
5857
5986
|
claimStatus.refetch();
|
|
5858
5987
|
onSuccess?.(result);
|
|
@@ -5939,7 +6068,7 @@ var styles14 = StyleSheet15.create({
|
|
|
5939
6068
|
});
|
|
5940
6069
|
|
|
5941
6070
|
// src/ui/game/EnterArcadePoolSheet.tsx
|
|
5942
|
-
import { useEffect as
|
|
6071
|
+
import { useEffect as useEffect19, useRef as useRef11, useCallback as useCallback26 } from "react";
|
|
5943
6072
|
import {
|
|
5944
6073
|
View as View15,
|
|
5945
6074
|
Text as Text16,
|
|
@@ -5970,20 +6099,20 @@ function EnterArcadePoolSheet({
|
|
|
5970
6099
|
const t = useDubsTheme();
|
|
5971
6100
|
const { wallet } = useDubs();
|
|
5972
6101
|
const mutation = useEnterArcadePool();
|
|
5973
|
-
const overlayOpacity =
|
|
5974
|
-
|
|
6102
|
+
const overlayOpacity = useRef11(new Animated6.Value(0)).current;
|
|
6103
|
+
useEffect19(() => {
|
|
5975
6104
|
Animated6.timing(overlayOpacity, {
|
|
5976
6105
|
toValue: visible ? 1 : 0,
|
|
5977
6106
|
duration: 250,
|
|
5978
6107
|
useNativeDriver: true
|
|
5979
6108
|
}).start();
|
|
5980
6109
|
}, [visible, overlayOpacity]);
|
|
5981
|
-
|
|
6110
|
+
useEffect19(() => {
|
|
5982
6111
|
if (visible) {
|
|
5983
6112
|
mutation.reset();
|
|
5984
6113
|
}
|
|
5985
6114
|
}, [visible]);
|
|
5986
|
-
|
|
6115
|
+
useEffect19(() => {
|
|
5987
6116
|
if (mutation.status === "success" && mutation.data) {
|
|
5988
6117
|
onSuccess?.(mutation.data);
|
|
5989
6118
|
const timer = setTimeout(() => {
|
|
@@ -5992,7 +6121,7 @@ function EnterArcadePoolSheet({
|
|
|
5992
6121
|
return () => clearTimeout(timer);
|
|
5993
6122
|
}
|
|
5994
6123
|
}, [mutation.status, mutation.data]);
|
|
5995
|
-
|
|
6124
|
+
useEffect19(() => {
|
|
5996
6125
|
if (mutation.status === "error" && mutation.error) {
|
|
5997
6126
|
onError?.(mutation.error);
|
|
5998
6127
|
}
|
|
@@ -6003,7 +6132,7 @@ function EnterArcadePoolSheet({
|
|
|
6003
6132
|
const potSol = (pool.buy_in_lamports * Number(totalPlayers) / 1e9).toFixed(4);
|
|
6004
6133
|
const isMutating = mutation.status !== "idle" && mutation.status !== "success" && mutation.status !== "error";
|
|
6005
6134
|
const canJoin = !isMutating && mutation.status !== "success";
|
|
6006
|
-
const handleJoin =
|
|
6135
|
+
const handleJoin = useCallback26(async () => {
|
|
6007
6136
|
if (!wallet.publicKey) return;
|
|
6008
6137
|
try {
|
|
6009
6138
|
await mutation.execute(pool.id);
|
|
@@ -6154,7 +6283,7 @@ var styles15 = StyleSheet16.create({
|
|
|
6154
6283
|
});
|
|
6155
6284
|
|
|
6156
6285
|
// src/ui/game/ArcadeLeaderboardSheet.tsx
|
|
6157
|
-
import { useEffect as
|
|
6286
|
+
import { useEffect as useEffect20, useRef as useRef12 } from "react";
|
|
6158
6287
|
import {
|
|
6159
6288
|
View as View16,
|
|
6160
6289
|
Text as Text17,
|
|
@@ -6182,15 +6311,15 @@ function ArcadeLeaderboardSheet({
|
|
|
6182
6311
|
}) {
|
|
6183
6312
|
const t = useDubsTheme();
|
|
6184
6313
|
const { pool, leaderboard, stats, loading, refetch } = useArcadePool(poolId);
|
|
6185
|
-
const overlayOpacity =
|
|
6186
|
-
|
|
6314
|
+
const overlayOpacity = useRef12(new Animated7.Value(0)).current;
|
|
6315
|
+
useEffect20(() => {
|
|
6187
6316
|
Animated7.timing(overlayOpacity, {
|
|
6188
6317
|
toValue: visible ? 1 : 0,
|
|
6189
6318
|
duration: 250,
|
|
6190
6319
|
useNativeDriver: true
|
|
6191
6320
|
}).start();
|
|
6192
6321
|
}, [visible, overlayOpacity]);
|
|
6193
|
-
|
|
6322
|
+
useEffect20(() => {
|
|
6194
6323
|
if (visible) refetch();
|
|
6195
6324
|
}, [visible]);
|
|
6196
6325
|
const renderItem = ({ item, index }) => {
|
|
@@ -6370,6 +6499,8 @@ export {
|
|
|
6370
6499
|
parseSolanaError,
|
|
6371
6500
|
signAndSendBase64Transaction,
|
|
6372
6501
|
useAppConfig,
|
|
6502
|
+
useArcadeBridge,
|
|
6503
|
+
useArcadeCountdown,
|
|
6373
6504
|
useArcadeGame,
|
|
6374
6505
|
useArcadePool,
|
|
6375
6506
|
useArcadePools,
|