@dubsdotapp/expo 0.5.12 → 0.5.14
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.js +420 -434
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +366 -381
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/ui/game/CreateGameSheet.tsx +20 -60
- package/src/ui/game/JoinGameSheet.tsx +1 -74
- package/src/ui/game/TeamButton.tsx +85 -0
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@ import { useCreateGame } from '../../hooks/useCreateGame';
|
|
|
17
17
|
import type { CreateGameMutationResult } from '../../hooks/useCreateGame';
|
|
18
18
|
import type { UnifiedEvent } from '../../types';
|
|
19
19
|
import { SolSlider } from './SolSlider';
|
|
20
|
+
import { TeamButton } from './TeamButton';
|
|
20
21
|
|
|
21
22
|
export interface CreateGameSheetProps {
|
|
22
23
|
visible: boolean;
|
|
@@ -198,59 +199,30 @@ export function CreateGameSheet({
|
|
|
198
199
|
</TouchableOpacity>
|
|
199
200
|
</View>
|
|
200
201
|
|
|
201
|
-
{/* Matchup banner */}
|
|
202
|
-
<View style={[styles.matchupBanner, { borderColor: t.border }]}>
|
|
203
|
-
<View style={styles.matchupTeam}>
|
|
204
|
-
{opponents[0]?.imageUrl ? (
|
|
205
|
-
<Image source={{ uri: opponents[0].imageUrl }} style={styles.matchupLogo} resizeMode="contain" />
|
|
206
|
-
) : (
|
|
207
|
-
<View style={[styles.matchupPlaceholder, { backgroundColor: homeColor + '20' }]}>
|
|
208
|
-
<Text style={[styles.matchupInitial, { color: homeColor }]}>{homeName.charAt(0)}</Text>
|
|
209
|
-
</View>
|
|
210
|
-
)}
|
|
211
|
-
<Text style={[styles.matchupName, { color: t.text }]} numberOfLines={1}>{homeName}</Text>
|
|
212
|
-
</View>
|
|
213
|
-
<Text style={[styles.matchupVs, { color: t.textMuted }]}>vs</Text>
|
|
214
|
-
<View style={styles.matchupTeam}>
|
|
215
|
-
{opponents[1]?.imageUrl ? (
|
|
216
|
-
<Image source={{ uri: opponents[1].imageUrl }} style={styles.matchupLogo} resizeMode="contain" />
|
|
217
|
-
) : (
|
|
218
|
-
<View style={[styles.matchupPlaceholder, { backgroundColor: awayColor + '20' }]}>
|
|
219
|
-
<Text style={[styles.matchupInitial, { color: awayColor }]}>{awayName.charAt(0)}</Text>
|
|
220
|
-
</View>
|
|
221
|
-
)}
|
|
222
|
-
<Text style={[styles.matchupName, { color: t.text }]} numberOfLines={1}>{awayName}</Text>
|
|
223
|
-
</View>
|
|
224
|
-
</View>
|
|
225
|
-
|
|
226
202
|
{/* Team Selection */}
|
|
227
203
|
<View style={styles.section}>
|
|
228
204
|
<Text style={[styles.sectionLabel, { color: t.textSecondary }]}>Pick Your Side</Text>
|
|
229
205
|
<View style={styles.teamsRow}>
|
|
230
|
-
<
|
|
231
|
-
|
|
206
|
+
<TeamButton
|
|
207
|
+
name={homeName}
|
|
208
|
+
imageUrl={opponents[0]?.imageUrl}
|
|
209
|
+
odds="—"
|
|
210
|
+
bets={0}
|
|
211
|
+
color={homeColor}
|
|
212
|
+
selected={selectedTeam === 'home'}
|
|
232
213
|
onPress={() => { setSelectedTeam('home'); onTeamSelect?.('home'); }}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
{
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
<TouchableOpacity
|
|
243
|
-
style={[styles.teamOption, { borderColor: selectedTeam === 'away' ? awayColor : t.border, backgroundColor: selectedTeam === 'away' ? awayColor + '15' : t.background }]}
|
|
214
|
+
t={t}
|
|
215
|
+
/>
|
|
216
|
+
<TeamButton
|
|
217
|
+
name={awayName}
|
|
218
|
+
imageUrl={opponents[1]?.imageUrl}
|
|
219
|
+
odds="—"
|
|
220
|
+
bets={0}
|
|
221
|
+
color={awayColor}
|
|
222
|
+
selected={selectedTeam === 'away'}
|
|
244
223
|
onPress={() => { setSelectedTeam('away'); onTeamSelect?.('away'); }}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
<Text style={[styles.teamLabel, { color: t.text }]}>{awayName}</Text>
|
|
248
|
-
{selectedTeam === 'away' && (
|
|
249
|
-
<View style={[styles.teamBadge, { backgroundColor: awayColor }]}>
|
|
250
|
-
<Text style={styles.teamBadgeText}>Selected</Text>
|
|
251
|
-
</View>
|
|
252
|
-
)}
|
|
253
|
-
</TouchableOpacity>
|
|
224
|
+
t={t}
|
|
225
|
+
/>
|
|
254
226
|
</View>
|
|
255
227
|
</View>
|
|
256
228
|
|
|
@@ -329,21 +301,9 @@ const styles = StyleSheet.create({
|
|
|
329
301
|
headerSub: { fontSize: 13, marginTop: 2 },
|
|
330
302
|
closeButton: { fontSize: 20, padding: 4 },
|
|
331
303
|
|
|
332
|
-
matchupBanner: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 16, borderBottomWidth: 1, gap: 16 },
|
|
333
|
-
matchupTeam: { flex: 1, alignItems: 'center', gap: 6 },
|
|
334
|
-
matchupLogo: { width: 40, height: 40 },
|
|
335
|
-
matchupPlaceholder: { width: 40, height: 40, borderRadius: 20, alignItems: 'center', justifyContent: 'center' },
|
|
336
|
-
matchupInitial: { fontSize: 18, fontWeight: '800' },
|
|
337
|
-
matchupName: { fontSize: 13, fontWeight: '600', textAlign: 'center' },
|
|
338
|
-
matchupVs: { fontSize: 13, fontWeight: '600' },
|
|
339
|
-
|
|
340
304
|
section: { gap: 10, paddingTop: 12 },
|
|
341
305
|
sectionLabel: { fontSize: 14, fontWeight: '600' },
|
|
342
|
-
teamsRow: { flexDirection: 'row', gap:
|
|
343
|
-
teamOption: { flex: 1, borderWidth: 2, borderRadius: 14, paddingVertical: 14, alignItems: 'center', gap: 6 },
|
|
344
|
-
teamLabel: { fontSize: 15, fontWeight: '700' },
|
|
345
|
-
teamBadge: { borderRadius: 8, paddingHorizontal: 10, paddingVertical: 3 },
|
|
346
|
-
teamBadgeText: { color: '#FFF', fontSize: 11, fontWeight: '700' },
|
|
306
|
+
teamsRow: { flexDirection: 'row', gap: 12 },
|
|
347
307
|
|
|
348
308
|
summaryCard: { marginTop: 12, borderRadius: 14, borderWidth: 1, overflow: 'hidden' },
|
|
349
309
|
summaryRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingVertical: 12 },
|
|
@@ -17,6 +17,7 @@ import { useJoinGame } from '../../hooks/useJoinGame';
|
|
|
17
17
|
import type { JoinGameMutationResult } from '../../hooks/useJoinGame';
|
|
18
18
|
import type { GameDetail } from '../../types';
|
|
19
19
|
import { SolSlider } from './SolSlider';
|
|
20
|
+
import { TeamButton } from './TeamButton';
|
|
20
21
|
|
|
21
22
|
export interface JoinGameSheetProps {
|
|
22
23
|
visible: boolean;
|
|
@@ -412,41 +413,6 @@ export function JoinGameSheet({
|
|
|
412
413
|
);
|
|
413
414
|
}
|
|
414
415
|
|
|
415
|
-
// ── TeamButton (internal, for sports/esports games) ──
|
|
416
|
-
|
|
417
|
-
function TeamButton({
|
|
418
|
-
name, imageUrl, odds, bets, color, selected, onPress, ImageComponent, t,
|
|
419
|
-
}: {
|
|
420
|
-
name: string; imageUrl?: string | null; odds: string; bets: number;
|
|
421
|
-
color: string; selected: boolean; onPress: () => void;
|
|
422
|
-
ImageComponent?: React.ComponentType<any>; t: any;
|
|
423
|
-
}) {
|
|
424
|
-
const [imgFailed, setImgFailed] = useState(false);
|
|
425
|
-
const Img = ImageComponent || require('react-native').Image;
|
|
426
|
-
const showImage = imageUrl && !imgFailed;
|
|
427
|
-
|
|
428
|
-
return (
|
|
429
|
-
<TouchableOpacity
|
|
430
|
-
style={[styles.teamOption, { borderColor: selected ? color : t.border, backgroundColor: selected ? color + '15' : t.background }]}
|
|
431
|
-
onPress={onPress}
|
|
432
|
-
activeOpacity={0.7}
|
|
433
|
-
>
|
|
434
|
-
{showImage ? (
|
|
435
|
-
<Img source={{ uri: imageUrl }} style={styles.teamLogo} resizeMode="contain" onError={() => setImgFailed(true)} />
|
|
436
|
-
) : (
|
|
437
|
-
<View style={[styles.teamLogo, styles.teamLogoPlaceholder]} />
|
|
438
|
-
)}
|
|
439
|
-
<Text style={[styles.teamName, { color: t.text }]} numberOfLines={1}>{name}</Text>
|
|
440
|
-
<Text style={[styles.teamOdds, { color }]}>{odds}x</Text>
|
|
441
|
-
<Text style={[styles.teamBets, { color: t.textMuted }]}>{bets} {bets === 1 ? 'bet' : 'bets'}</Text>
|
|
442
|
-
{selected && (
|
|
443
|
-
<View style={[styles.teamBadge, { backgroundColor: color }]}>
|
|
444
|
-
<Text style={styles.teamBadgeText}>Selected</Text>
|
|
445
|
-
</View>
|
|
446
|
-
)}
|
|
447
|
-
</TouchableOpacity>
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
416
|
|
|
451
417
|
const styles = StyleSheet.create({
|
|
452
418
|
overlay: {
|
|
@@ -642,43 +608,4 @@ const styles = StyleSheet.create({
|
|
|
642
608
|
alignItems: 'center',
|
|
643
609
|
gap: 10,
|
|
644
610
|
},
|
|
645
|
-
// Team button styles
|
|
646
|
-
teamOption: {
|
|
647
|
-
flex: 1,
|
|
648
|
-
borderWidth: 2,
|
|
649
|
-
borderRadius: 16,
|
|
650
|
-
padding: 16,
|
|
651
|
-
alignItems: 'center',
|
|
652
|
-
gap: 8,
|
|
653
|
-
},
|
|
654
|
-
teamLogo: {
|
|
655
|
-
width: 48,
|
|
656
|
-
height: 48,
|
|
657
|
-
borderRadius: 24,
|
|
658
|
-
},
|
|
659
|
-
teamLogoPlaceholder: {
|
|
660
|
-
backgroundColor: 'rgba(128,128,128,0.2)',
|
|
661
|
-
},
|
|
662
|
-
teamName: {
|
|
663
|
-
fontSize: 15,
|
|
664
|
-
fontWeight: '700',
|
|
665
|
-
},
|
|
666
|
-
teamOdds: {
|
|
667
|
-
fontSize: 20,
|
|
668
|
-
fontWeight: '800',
|
|
669
|
-
},
|
|
670
|
-
teamBets: {
|
|
671
|
-
fontSize: 12,
|
|
672
|
-
},
|
|
673
|
-
teamBadge: {
|
|
674
|
-
borderRadius: 8,
|
|
675
|
-
paddingHorizontal: 12,
|
|
676
|
-
paddingVertical: 4,
|
|
677
|
-
marginTop: 4,
|
|
678
|
-
},
|
|
679
|
-
teamBadgeText: {
|
|
680
|
-
color: '#FFF',
|
|
681
|
-
fontSize: 12,
|
|
682
|
-
fontWeight: '700',
|
|
683
|
-
},
|
|
684
611
|
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface TeamButtonProps {
|
|
5
|
+
name: string;
|
|
6
|
+
imageUrl?: string | null;
|
|
7
|
+
odds: string;
|
|
8
|
+
bets: number;
|
|
9
|
+
color: string;
|
|
10
|
+
selected: boolean;
|
|
11
|
+
onPress: () => void;
|
|
12
|
+
ImageComponent?: React.ComponentType<any>;
|
|
13
|
+
t: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function TeamButton({
|
|
17
|
+
name, imageUrl, odds, bets, color, selected, onPress, ImageComponent, t,
|
|
18
|
+
}: TeamButtonProps) {
|
|
19
|
+
const [imgFailed, setImgFailed] = useState(false);
|
|
20
|
+
const Img = ImageComponent || require('react-native').Image;
|
|
21
|
+
const showImage = imageUrl && !imgFailed;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<TouchableOpacity
|
|
25
|
+
style={[styles.teamOption, { borderColor: selected ? color : t.border, backgroundColor: selected ? color + '15' : t.background }]}
|
|
26
|
+
onPress={onPress}
|
|
27
|
+
activeOpacity={0.7}
|
|
28
|
+
>
|
|
29
|
+
{showImage ? (
|
|
30
|
+
<Img source={{ uri: imageUrl }} style={styles.teamLogo} resizeMode="contain" onError={() => setImgFailed(true)} />
|
|
31
|
+
) : (
|
|
32
|
+
<View style={[styles.teamLogo, styles.teamLogoPlaceholder]} />
|
|
33
|
+
)}
|
|
34
|
+
<Text style={[styles.teamName, { color: t.text }]} numberOfLines={1}>{name}</Text>
|
|
35
|
+
{odds !== '—' && <Text style={[styles.teamOdds, { color }]}>{odds}x</Text>}
|
|
36
|
+
{bets > 0 && <Text style={[styles.teamBets, { color: t.textMuted }]}>{bets} {bets === 1 ? 'bet' : 'bets'}</Text>}
|
|
37
|
+
{selected && (
|
|
38
|
+
<View style={[styles.teamBadge, { backgroundColor: color }]}>
|
|
39
|
+
<Text style={styles.teamBadgeText}>Selected</Text>
|
|
40
|
+
</View>
|
|
41
|
+
)}
|
|
42
|
+
</TouchableOpacity>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const styles = StyleSheet.create({
|
|
47
|
+
teamOption: {
|
|
48
|
+
flex: 1,
|
|
49
|
+
borderWidth: 2,
|
|
50
|
+
borderRadius: 16,
|
|
51
|
+
padding: 16,
|
|
52
|
+
alignItems: 'center',
|
|
53
|
+
gap: 8,
|
|
54
|
+
},
|
|
55
|
+
teamLogo: {
|
|
56
|
+
width: 48,
|
|
57
|
+
height: 48,
|
|
58
|
+
borderRadius: 24,
|
|
59
|
+
},
|
|
60
|
+
teamLogoPlaceholder: {
|
|
61
|
+
backgroundColor: 'rgba(128,128,128,0.2)',
|
|
62
|
+
},
|
|
63
|
+
teamName: {
|
|
64
|
+
fontSize: 15,
|
|
65
|
+
fontWeight: '700',
|
|
66
|
+
},
|
|
67
|
+
teamOdds: {
|
|
68
|
+
fontSize: 20,
|
|
69
|
+
fontWeight: '800',
|
|
70
|
+
},
|
|
71
|
+
teamBets: {
|
|
72
|
+
fontSize: 12,
|
|
73
|
+
},
|
|
74
|
+
teamBadge: {
|
|
75
|
+
borderRadius: 8,
|
|
76
|
+
paddingHorizontal: 12,
|
|
77
|
+
paddingVertical: 4,
|
|
78
|
+
marginTop: 4,
|
|
79
|
+
},
|
|
80
|
+
teamBadgeText: {
|
|
81
|
+
color: '#FFF',
|
|
82
|
+
fontSize: 12,
|
|
83
|
+
fontWeight: '700',
|
|
84
|
+
},
|
|
85
|
+
});
|