@dubsdotapp/expo 0.5.17 → 0.5.18
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 +2081 -0
- package/dist/index.d.ts +2081 -0
- package/dist/index.js +1916 -147
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1868 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -4
- package/src/chat/hooks.ts +320 -0
- package/src/chat/index.ts +40 -0
- package/src/chat/provider.tsx +213 -0
- package/src/chat/socket.ts +175 -0
- package/src/chat/types.ts +146 -0
- package/src/client.ts +182 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useEnterJackpot.ts +80 -0
- package/src/hooks/useJackpot.ts +37 -0
- package/src/hooks/useJackpotHistory.ts +34 -0
- package/src/index.ts +55 -0
- package/src/types.ts +60 -0
- package/src/ui/game/JoinGameSheet.tsx +1 -1
- package/src/ui/index.ts +4 -0
- package/src/ui/jackpot/JackpotCard.tsx +417 -0
- package/src/ui/jackpot/JackpotSheet.tsx +683 -0
- package/src/ui/jackpot/JackpotWidget.tsx +74 -0
- package/src/ui/jackpot/index.ts +6 -0
package/src/index.ts
CHANGED
|
@@ -77,6 +77,13 @@ export type {
|
|
|
77
77
|
BuildArcadeEntryResult,
|
|
78
78
|
EnterArcadePoolResult,
|
|
79
79
|
ArcadePoolResult,
|
|
80
|
+
JackpotRound,
|
|
81
|
+
JackpotLastWinner,
|
|
82
|
+
JackpotEntry,
|
|
83
|
+
JackpotRoundResult,
|
|
84
|
+
JackpotConfig,
|
|
85
|
+
BuildJackpotEnterResult,
|
|
86
|
+
ConfirmJackpotEnterResult,
|
|
80
87
|
} from './types';
|
|
81
88
|
|
|
82
89
|
// Provider
|
|
@@ -111,6 +118,9 @@ export {
|
|
|
111
118
|
useEnterArcadePool,
|
|
112
119
|
useArcadeCountdown,
|
|
113
120
|
useArcadeBridge,
|
|
121
|
+
useJackpot,
|
|
122
|
+
useJackpotHistory,
|
|
123
|
+
useEnterJackpot,
|
|
114
124
|
} from './hooks';
|
|
115
125
|
export type {
|
|
116
126
|
CreateGameMutationResult,
|
|
@@ -129,6 +139,9 @@ export type {
|
|
|
129
139
|
UseArcadeBridgeResult,
|
|
130
140
|
HighlightVideo,
|
|
131
141
|
ShortVideo,
|
|
142
|
+
UseJackpotResult,
|
|
143
|
+
UseJackpotHistoryResult,
|
|
144
|
+
EnterJackpotMutationResult,
|
|
132
145
|
} from './hooks';
|
|
133
146
|
|
|
134
147
|
export { useHighlights, useShorts } from './hooks';
|
|
@@ -155,6 +168,48 @@ export type {
|
|
|
155
168
|
ArcadeLeaderboardSheetProps,
|
|
156
169
|
} from './ui';
|
|
157
170
|
|
|
171
|
+
// Jackpot widgets
|
|
172
|
+
export { JackpotCard, JackpotSheet, JackpotWidget } from './ui';
|
|
173
|
+
export type { JackpotCardProps, JackpotSheetProps, JackpotWidgetProps } from './ui';
|
|
174
|
+
|
|
175
|
+
// Chat module
|
|
176
|
+
export {
|
|
177
|
+
ChatProvider,
|
|
178
|
+
useChatContext,
|
|
179
|
+
ChatSocket,
|
|
180
|
+
useChatStatus,
|
|
181
|
+
useChatMessages,
|
|
182
|
+
useSendMessage,
|
|
183
|
+
useOnlineUsers,
|
|
184
|
+
useUnreadCount,
|
|
185
|
+
useConversations,
|
|
186
|
+
useDirectMessages,
|
|
187
|
+
useFriends,
|
|
188
|
+
useFriendRequests,
|
|
189
|
+
useSearchUsers,
|
|
190
|
+
useSendFriendRequest,
|
|
191
|
+
useRespondToFriendRequest,
|
|
192
|
+
} from './chat';
|
|
193
|
+
export type {
|
|
194
|
+
ChatProviderProps,
|
|
195
|
+
ChatContextValue,
|
|
196
|
+
ChatSocketConfig,
|
|
197
|
+
ChatSocketListeners,
|
|
198
|
+
ChatMessage,
|
|
199
|
+
ChatMention,
|
|
200
|
+
ChatPayment,
|
|
201
|
+
DirectMessage,
|
|
202
|
+
Conversation,
|
|
203
|
+
FriendUser,
|
|
204
|
+
FriendRequest,
|
|
205
|
+
OnlineUser,
|
|
206
|
+
TypingEvent,
|
|
207
|
+
ChatNotification,
|
|
208
|
+
ChatConnectionStatus,
|
|
209
|
+
SendMessageParams,
|
|
210
|
+
SendDMParams,
|
|
211
|
+
} from './chat';
|
|
212
|
+
|
|
158
213
|
// Utils
|
|
159
214
|
export { signAndSendBase64Transaction } from './utils/transaction';
|
|
160
215
|
export { getDeviceInfo, isSolanaSeeker } from './utils/device';
|
package/src/types.ts
CHANGED
|
@@ -581,6 +581,66 @@ export interface ArcadePoolResult {
|
|
|
581
581
|
best_score: number;
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
+
// ── Jackpot ──
|
|
585
|
+
|
|
586
|
+
export interface JackpotRound {
|
|
587
|
+
roundId: string;
|
|
588
|
+
status: 'Open' | 'Locked' | 'Resolved';
|
|
589
|
+
totalPotLamports: string;
|
|
590
|
+
totalPotSol: number;
|
|
591
|
+
entryCount: number;
|
|
592
|
+
totalWeight: string;
|
|
593
|
+
timeRemainingSlots: number;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
export interface JackpotLastWinner {
|
|
597
|
+
roundId: string;
|
|
598
|
+
winner: string;
|
|
599
|
+
winAmount: string;
|
|
600
|
+
winAmountSol: number;
|
|
601
|
+
totalPot: string;
|
|
602
|
+
entryCount: number;
|
|
603
|
+
timestamp: string | null;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export interface JackpotEntry {
|
|
607
|
+
player: string;
|
|
608
|
+
weight: string;
|
|
609
|
+
weightSol: number;
|
|
610
|
+
oddsPercent: string;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export interface JackpotRoundResult {
|
|
614
|
+
roundId: string;
|
|
615
|
+
winner: string;
|
|
616
|
+
winAmount: string;
|
|
617
|
+
winAmountSol: number;
|
|
618
|
+
totalPot: string;
|
|
619
|
+
totalPotSol: number;
|
|
620
|
+
entryCount: number;
|
|
621
|
+
timestamp: string;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export interface JackpotConfig {
|
|
625
|
+
feeBasisPoints: number;
|
|
626
|
+
roundDurationSlots: string;
|
|
627
|
+
minEntryLamports: number;
|
|
628
|
+
minEntrySol: number;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export interface BuildJackpotEnterResult {
|
|
632
|
+
transaction: string;
|
|
633
|
+
roundId: string;
|
|
634
|
+
amount: string;
|
|
635
|
+
amountSol: number;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export interface ConfirmJackpotEnterResult {
|
|
639
|
+
attributed: boolean;
|
|
640
|
+
appId: number;
|
|
641
|
+
signature: string;
|
|
642
|
+
}
|
|
643
|
+
|
|
584
644
|
// ── UI Config (developer branding) ──
|
|
585
645
|
|
|
586
646
|
export interface UiConfig {
|
|
@@ -88,7 +88,7 @@ export function JoinGameSheet({
|
|
|
88
88
|
|
|
89
89
|
const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
|
|
90
90
|
|
|
91
|
-
const [selectedTeam, setSelectedTeam] = useState<'home' | 'away' | null>(null);
|
|
91
|
+
const [selectedTeam, setSelectedTeam] = useState<'home' | 'away' | 'draw' | null>(null);
|
|
92
92
|
const [wager, setWager] = useState(game.buyIn);
|
|
93
93
|
const [showSuccess, setShowSuccess] = useState(false);
|
|
94
94
|
|
package/src/ui/index.ts
CHANGED
|
@@ -15,6 +15,10 @@ export type { DubsTheme } from './theme';
|
|
|
15
15
|
|
|
16
16
|
// Game widgets
|
|
17
17
|
export { GamePoster, LivePoolsCard, PickWinnerCard, PlayersCard, JoinGameButton, CreateCustomGameSheet, CreateGameSheet, JoinGameSheet, ClaimPrizeSheet, ClaimButton, EnterArcadePoolSheet, ArcadeLeaderboardSheet, SolSlider } from './game';
|
|
18
|
+
|
|
19
|
+
// Jackpot widgets
|
|
20
|
+
export { JackpotCard, JackpotSheet, JackpotWidget } from './jackpot';
|
|
21
|
+
export type { JackpotCardProps, JackpotSheetProps, JackpotWidgetProps } from './jackpot';
|
|
18
22
|
export type {
|
|
19
23
|
GamePosterProps,
|
|
20
24
|
LivePoolsCardProps,
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
Text,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
Animated,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
Image,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import type { JackpotRound, JackpotLastWinner, JackpotEntry } from '../../types';
|
|
11
|
+
import type { ViewStyle } from 'react-native';
|
|
12
|
+
|
|
13
|
+
export interface JackpotCardProps {
|
|
14
|
+
round: JackpotRound | null;
|
|
15
|
+
lastWinner?: JackpotLastWinner | null;
|
|
16
|
+
entries?: JackpotEntry[];
|
|
17
|
+
onPress?: () => void;
|
|
18
|
+
style?: ViewStyle;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function formatSOL(lamports: string | number): string {
|
|
22
|
+
const val = typeof lamports === 'string' ? parseInt(lamports, 10) : lamports;
|
|
23
|
+
if (isNaN(val) || val === 0) return '0';
|
|
24
|
+
const sol = val / 1_000_000_000;
|
|
25
|
+
// No trailing zeros
|
|
26
|
+
if (sol >= 100) return sol.toFixed(0);
|
|
27
|
+
if (sol >= 1) return sol.toFixed(2);
|
|
28
|
+
if (sol >= 0.01) return sol.toFixed(3);
|
|
29
|
+
return sol.toFixed(4);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function truncateWallet(addr: string): string {
|
|
33
|
+
if (!addr || addr.length < 8) return addr || '';
|
|
34
|
+
return `${addr.slice(0, 4)}...${addr.slice(-4)}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function JackpotCard({ round, lastWinner, entries, onPress, style }: JackpotCardProps) {
|
|
38
|
+
const shimmerAnim = useRef(new Animated.Value(-1)).current;
|
|
39
|
+
const pulseAnim = useRef(new Animated.Value(0.4)).current;
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
// Shimmer sweep: matches web heroSweep (4s)
|
|
43
|
+
const shimmer = Animated.loop(
|
|
44
|
+
Animated.sequence([
|
|
45
|
+
Animated.timing(shimmerAnim, { toValue: 1, duration: 4000, useNativeDriver: true }),
|
|
46
|
+
Animated.delay(500),
|
|
47
|
+
Animated.timing(shimmerAnim, { toValue: -1, duration: 0, useNativeDriver: true }),
|
|
48
|
+
]),
|
|
49
|
+
);
|
|
50
|
+
shimmer.start();
|
|
51
|
+
|
|
52
|
+
// Status dot pulse
|
|
53
|
+
const pulse = Animated.loop(
|
|
54
|
+
Animated.sequence([
|
|
55
|
+
Animated.timing(pulseAnim, { toValue: 1, duration: 1000, useNativeDriver: true }),
|
|
56
|
+
Animated.timing(pulseAnim, { toValue: 0.4, duration: 1000, useNativeDriver: true }),
|
|
57
|
+
]),
|
|
58
|
+
);
|
|
59
|
+
pulse.start();
|
|
60
|
+
|
|
61
|
+
return () => { shimmer.stop(); pulse.stop(); };
|
|
62
|
+
}, [shimmerAnim, pulseAnim]);
|
|
63
|
+
|
|
64
|
+
const potSol = round ? formatSOL(round.totalPotLamports) : '0';
|
|
65
|
+
const isOpen = round?.status === 'Open';
|
|
66
|
+
const entryCount = round?.entryCount ?? 0;
|
|
67
|
+
const totalWeight = round ? Number(BigInt(round.totalWeight || '0')) : 0;
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<TouchableOpacity
|
|
71
|
+
activeOpacity={0.9}
|
|
72
|
+
onPress={onPress}
|
|
73
|
+
style={[styles.card, style]}
|
|
74
|
+
>
|
|
75
|
+
{/* Green accent gradient background */}
|
|
76
|
+
<View style={styles.gradientBg} />
|
|
77
|
+
|
|
78
|
+
{/* Shimmer sweep overlay */}
|
|
79
|
+
<Animated.View
|
|
80
|
+
style={[
|
|
81
|
+
styles.shimmer,
|
|
82
|
+
{
|
|
83
|
+
transform: [{
|
|
84
|
+
translateX: shimmerAnim.interpolate({
|
|
85
|
+
inputRange: [-1, 1],
|
|
86
|
+
outputRange: [-400, 400],
|
|
87
|
+
}),
|
|
88
|
+
}],
|
|
89
|
+
},
|
|
90
|
+
]}
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
{/* Bottom accent bar */}
|
|
94
|
+
<View style={styles.accentBar} />
|
|
95
|
+
|
|
96
|
+
{/* Content */}
|
|
97
|
+
<View style={styles.content}>
|
|
98
|
+
{/* Status badge */}
|
|
99
|
+
<View style={styles.statusRow}>
|
|
100
|
+
<View style={[styles.statusBadge, isOpen ? styles.statusOpen : styles.statusClosed]}>
|
|
101
|
+
{isOpen && (
|
|
102
|
+
<Animated.View style={[styles.statusDot, { opacity: pulseAnim }]} />
|
|
103
|
+
)}
|
|
104
|
+
<Text style={[styles.statusText, { color: isOpen ? '#22c55e' : '#9ca3af' }]}>
|
|
105
|
+
{isOpen ? 'Open' : round?.status ?? 'Loading'}
|
|
106
|
+
</Text>
|
|
107
|
+
</View>
|
|
108
|
+
<Text style={styles.entryCountText}>{entryCount} player{entryCount !== 1 ? 's' : ''}</Text>
|
|
109
|
+
</View>
|
|
110
|
+
|
|
111
|
+
{/* Hero pot section */}
|
|
112
|
+
<View style={styles.heroSection}>
|
|
113
|
+
<View style={styles.potInfo}>
|
|
114
|
+
<Text style={styles.jackpotLabel}>JACKPOT</Text>
|
|
115
|
+
<Text style={styles.potValue}>{potSol} SOL</Text>
|
|
116
|
+
</View>
|
|
117
|
+
<Text style={styles.potEmoji}>🤑</Text>
|
|
118
|
+
</View>
|
|
119
|
+
|
|
120
|
+
{/* Info grid: Your Chance / Players / Last Winner */}
|
|
121
|
+
<View style={styles.infoGrid}>
|
|
122
|
+
<View style={styles.infoCard}>
|
|
123
|
+
<Text style={styles.infoLabel}>PLAYERS</Text>
|
|
124
|
+
<Text style={styles.infoValue}>{entryCount}</Text>
|
|
125
|
+
</View>
|
|
126
|
+
<View style={styles.infoCard}>
|
|
127
|
+
<Text style={styles.infoLabel}>TOTAL POT</Text>
|
|
128
|
+
<Text style={[styles.infoValue, { color: '#4ade80' }]}>{potSol}</Text>
|
|
129
|
+
</View>
|
|
130
|
+
<View style={styles.infoCard}>
|
|
131
|
+
<Text style={styles.infoLabel}>LAST WIN</Text>
|
|
132
|
+
<Text style={[styles.infoValue, { color: '#22c55e' }]}>
|
|
133
|
+
{lastWinner ? formatSOL(lastWinner.winAmount) : '—'}
|
|
134
|
+
</Text>
|
|
135
|
+
</View>
|
|
136
|
+
</View>
|
|
137
|
+
|
|
138
|
+
{/* Player carousel (horizontal scroll of entry chips) */}
|
|
139
|
+
{entries && entries.length > 0 && (
|
|
140
|
+
<View style={styles.playersSection}>
|
|
141
|
+
<View style={styles.playersSectionHeader}>
|
|
142
|
+
<Text style={styles.playersSectionTitle}>Players in Round</Text>
|
|
143
|
+
<View style={styles.activeCountBadge}>
|
|
144
|
+
<Text style={styles.activeCountText}>{entries.length}</Text>
|
|
145
|
+
</View>
|
|
146
|
+
</View>
|
|
147
|
+
<View style={styles.playersCarousel}>
|
|
148
|
+
{entries.slice(0, 8).map((entry, i) => {
|
|
149
|
+
const odds = entry.oddsPercent;
|
|
150
|
+
return (
|
|
151
|
+
<View key={`${entry.player}-${i}`} style={styles.playerCard}>
|
|
152
|
+
{/* Avatar placeholder */}
|
|
153
|
+
<View style={styles.playerAvatar}>
|
|
154
|
+
<Text style={styles.playerAvatarText}>
|
|
155
|
+
{entry.player.slice(0, 2).toUpperCase()}
|
|
156
|
+
</Text>
|
|
157
|
+
</View>
|
|
158
|
+
<Text style={styles.playerWallet} numberOfLines={1}>
|
|
159
|
+
{truncateWallet(entry.player)}
|
|
160
|
+
</Text>
|
|
161
|
+
<Text style={styles.playerWager}>{entry.weightSol.toFixed(2)} SOL</Text>
|
|
162
|
+
<Text style={styles.playerOdds}>{odds}%</Text>
|
|
163
|
+
</View>
|
|
164
|
+
);
|
|
165
|
+
})}
|
|
166
|
+
{entries.length > 8 && (
|
|
167
|
+
<View style={styles.playerCardMore}>
|
|
168
|
+
<Text style={styles.playerMoreText}>+{entries.length - 8}</Text>
|
|
169
|
+
</View>
|
|
170
|
+
)}
|
|
171
|
+
</View>
|
|
172
|
+
</View>
|
|
173
|
+
)}
|
|
174
|
+
|
|
175
|
+
{/* Place Bet CTA */}
|
|
176
|
+
<TouchableOpacity
|
|
177
|
+
style={styles.placeBetButton}
|
|
178
|
+
activeOpacity={0.85}
|
|
179
|
+
onPress={onPress}
|
|
180
|
+
>
|
|
181
|
+
<Text style={styles.placeBetText}>Place Bet</Text>
|
|
182
|
+
</TouchableOpacity>
|
|
183
|
+
</View>
|
|
184
|
+
</TouchableOpacity>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const styles = StyleSheet.create({
|
|
189
|
+
card: {
|
|
190
|
+
borderRadius: 16,
|
|
191
|
+
borderWidth: 1,
|
|
192
|
+
borderColor: 'rgba(34, 197, 94, 0.2)',
|
|
193
|
+
backgroundColor: '#0c0c14',
|
|
194
|
+
overflow: 'hidden',
|
|
195
|
+
position: 'relative',
|
|
196
|
+
},
|
|
197
|
+
gradientBg: {
|
|
198
|
+
...StyleSheet.absoluteFillObject,
|
|
199
|
+
backgroundColor: 'rgba(34, 197, 94, 0.04)',
|
|
200
|
+
},
|
|
201
|
+
shimmer: {
|
|
202
|
+
position: 'absolute',
|
|
203
|
+
top: 0,
|
|
204
|
+
bottom: 0,
|
|
205
|
+
width: 120,
|
|
206
|
+
backgroundColor: 'rgba(34, 197, 94, 0.08)',
|
|
207
|
+
},
|
|
208
|
+
accentBar: {
|
|
209
|
+
position: 'absolute',
|
|
210
|
+
bottom: 0,
|
|
211
|
+
left: 0,
|
|
212
|
+
right: '40%' as any,
|
|
213
|
+
height: 2,
|
|
214
|
+
backgroundColor: '#22c55e',
|
|
215
|
+
},
|
|
216
|
+
content: {
|
|
217
|
+
padding: 16,
|
|
218
|
+
gap: 12,
|
|
219
|
+
},
|
|
220
|
+
// Status row
|
|
221
|
+
statusRow: {
|
|
222
|
+
flexDirection: 'row',
|
|
223
|
+
alignItems: 'center',
|
|
224
|
+
gap: 8,
|
|
225
|
+
},
|
|
226
|
+
statusBadge: {
|
|
227
|
+
flexDirection: 'row',
|
|
228
|
+
alignItems: 'center',
|
|
229
|
+
gap: 6,
|
|
230
|
+
paddingHorizontal: 10,
|
|
231
|
+
paddingVertical: 4,
|
|
232
|
+
borderRadius: 100,
|
|
233
|
+
},
|
|
234
|
+
statusOpen: {
|
|
235
|
+
backgroundColor: 'rgba(34, 197, 94, 0.15)',
|
|
236
|
+
},
|
|
237
|
+
statusClosed: {
|
|
238
|
+
backgroundColor: 'rgba(156, 163, 175, 0.15)',
|
|
239
|
+
},
|
|
240
|
+
statusDot: {
|
|
241
|
+
width: 6,
|
|
242
|
+
height: 6,
|
|
243
|
+
borderRadius: 3,
|
|
244
|
+
backgroundColor: '#22c55e',
|
|
245
|
+
},
|
|
246
|
+
statusText: {
|
|
247
|
+
fontSize: 12,
|
|
248
|
+
fontWeight: '700',
|
|
249
|
+
},
|
|
250
|
+
entryCountText: {
|
|
251
|
+
fontSize: 12,
|
|
252
|
+
color: '#6b6b6b',
|
|
253
|
+
fontWeight: '500',
|
|
254
|
+
},
|
|
255
|
+
// Hero pot
|
|
256
|
+
heroSection: {
|
|
257
|
+
flexDirection: 'row',
|
|
258
|
+
alignItems: 'center',
|
|
259
|
+
justifyContent: 'space-between',
|
|
260
|
+
},
|
|
261
|
+
potInfo: {
|
|
262
|
+
flex: 1,
|
|
263
|
+
},
|
|
264
|
+
jackpotLabel: {
|
|
265
|
+
fontSize: 10,
|
|
266
|
+
fontWeight: '600',
|
|
267
|
+
color: '#6b6b6b',
|
|
268
|
+
letterSpacing: 3,
|
|
269
|
+
textTransform: 'uppercase',
|
|
270
|
+
marginBottom: 4,
|
|
271
|
+
},
|
|
272
|
+
potValue: {
|
|
273
|
+
fontSize: 36,
|
|
274
|
+
fontWeight: '900',
|
|
275
|
+
color: '#4ade80',
|
|
276
|
+
letterSpacing: -1,
|
|
277
|
+
},
|
|
278
|
+
potEmoji: {
|
|
279
|
+
fontSize: 40,
|
|
280
|
+
opacity: 0.2,
|
|
281
|
+
},
|
|
282
|
+
// Info grid
|
|
283
|
+
infoGrid: {
|
|
284
|
+
flexDirection: 'row',
|
|
285
|
+
gap: 8,
|
|
286
|
+
},
|
|
287
|
+
infoCard: {
|
|
288
|
+
flex: 1,
|
|
289
|
+
borderRadius: 12,
|
|
290
|
+
borderWidth: 1,
|
|
291
|
+
borderColor: '#1e1e2a',
|
|
292
|
+
backgroundColor: '#0c0c14',
|
|
293
|
+
padding: 12,
|
|
294
|
+
},
|
|
295
|
+
infoLabel: {
|
|
296
|
+
fontSize: 9,
|
|
297
|
+
fontWeight: '600',
|
|
298
|
+
color: '#6b6b6b',
|
|
299
|
+
letterSpacing: 2,
|
|
300
|
+
textTransform: 'uppercase',
|
|
301
|
+
marginBottom: 4,
|
|
302
|
+
},
|
|
303
|
+
infoValue: {
|
|
304
|
+
fontSize: 18,
|
|
305
|
+
fontWeight: '700',
|
|
306
|
+
color: '#FFFFFF',
|
|
307
|
+
},
|
|
308
|
+
// Players section
|
|
309
|
+
playersSection: {
|
|
310
|
+
borderRadius: 12,
|
|
311
|
+
borderWidth: 1,
|
|
312
|
+
borderColor: '#1e1e2a',
|
|
313
|
+
backgroundColor: 'rgba(139, 92, 246, 0.04)',
|
|
314
|
+
padding: 12,
|
|
315
|
+
overflow: 'hidden',
|
|
316
|
+
},
|
|
317
|
+
playersSectionHeader: {
|
|
318
|
+
flexDirection: 'row',
|
|
319
|
+
alignItems: 'center',
|
|
320
|
+
justifyContent: 'space-between',
|
|
321
|
+
marginBottom: 10,
|
|
322
|
+
},
|
|
323
|
+
playersSectionTitle: {
|
|
324
|
+
fontSize: 13,
|
|
325
|
+
fontWeight: '600',
|
|
326
|
+
color: '#a0a0a0',
|
|
327
|
+
},
|
|
328
|
+
activeCountBadge: {
|
|
329
|
+
backgroundColor: 'rgba(34, 197, 94, 0.15)',
|
|
330
|
+
paddingHorizontal: 8,
|
|
331
|
+
paddingVertical: 2,
|
|
332
|
+
borderRadius: 100,
|
|
333
|
+
},
|
|
334
|
+
activeCountText: {
|
|
335
|
+
fontSize: 11,
|
|
336
|
+
fontWeight: '700',
|
|
337
|
+
color: '#22c55e',
|
|
338
|
+
},
|
|
339
|
+
playersCarousel: {
|
|
340
|
+
flexDirection: 'row',
|
|
341
|
+
gap: 10,
|
|
342
|
+
},
|
|
343
|
+
playerCard: {
|
|
344
|
+
width: 96,
|
|
345
|
+
borderRadius: 12,
|
|
346
|
+
borderWidth: 1.5,
|
|
347
|
+
borderColor: 'rgba(139, 92, 246, 0.4)',
|
|
348
|
+
backgroundColor: 'rgba(139, 92, 246, 0.08)',
|
|
349
|
+
padding: 10,
|
|
350
|
+
alignItems: 'center',
|
|
351
|
+
gap: 4,
|
|
352
|
+
},
|
|
353
|
+
playerAvatar: {
|
|
354
|
+
width: 40,
|
|
355
|
+
height: 40,
|
|
356
|
+
borderRadius: 20,
|
|
357
|
+
borderWidth: 1.5,
|
|
358
|
+
borderColor: '#8b5cf6',
|
|
359
|
+
backgroundColor: 'rgba(139, 92, 246, 0.2)',
|
|
360
|
+
alignItems: 'center',
|
|
361
|
+
justifyContent: 'center',
|
|
362
|
+
},
|
|
363
|
+
playerAvatarText: {
|
|
364
|
+
fontSize: 14,
|
|
365
|
+
fontWeight: '700',
|
|
366
|
+
color: '#a78bfa',
|
|
367
|
+
},
|
|
368
|
+
playerWallet: {
|
|
369
|
+
fontSize: 10,
|
|
370
|
+
fontWeight: '500',
|
|
371
|
+
color: '#a0a0a0',
|
|
372
|
+
width: '100%',
|
|
373
|
+
textAlign: 'center',
|
|
374
|
+
},
|
|
375
|
+
playerWager: {
|
|
376
|
+
fontSize: 12,
|
|
377
|
+
fontWeight: '600',
|
|
378
|
+
color: '#a78bfa',
|
|
379
|
+
},
|
|
380
|
+
playerOdds: {
|
|
381
|
+
fontSize: 10,
|
|
382
|
+
fontWeight: '700',
|
|
383
|
+
color: '#22c55e',
|
|
384
|
+
},
|
|
385
|
+
playerCardMore: {
|
|
386
|
+
width: 96,
|
|
387
|
+
borderRadius: 12,
|
|
388
|
+
borderWidth: 1.5,
|
|
389
|
+
borderColor: '#1e1e2a',
|
|
390
|
+
backgroundColor: '#14141e',
|
|
391
|
+
alignItems: 'center',
|
|
392
|
+
justifyContent: 'center',
|
|
393
|
+
},
|
|
394
|
+
playerMoreText: {
|
|
395
|
+
fontSize: 16,
|
|
396
|
+
fontWeight: '700',
|
|
397
|
+
color: '#6b6b6b',
|
|
398
|
+
},
|
|
399
|
+
// Place bet CTA
|
|
400
|
+
placeBetButton: {
|
|
401
|
+
height: 52,
|
|
402
|
+
borderRadius: 12,
|
|
403
|
+
alignItems: 'center',
|
|
404
|
+
justifyContent: 'center',
|
|
405
|
+
backgroundColor: '#22c55e',
|
|
406
|
+
shadowColor: '#22c55e',
|
|
407
|
+
shadowOffset: { width: 0, height: 4 },
|
|
408
|
+
shadowOpacity: 0.25,
|
|
409
|
+
shadowRadius: 12,
|
|
410
|
+
elevation: 6,
|
|
411
|
+
},
|
|
412
|
+
placeBetText: {
|
|
413
|
+
color: '#FFFFFF',
|
|
414
|
+
fontSize: 16,
|
|
415
|
+
fontWeight: '700',
|
|
416
|
+
},
|
|
417
|
+
});
|