@multiplayer-app/session-recorder-react-native 0.0.1-alpha.1 → 0.0.1-alpha.10
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/RRWEB_INTEGRATION.md +336 -0
- package/VIEWSHOT_INTEGRATION_TEST.md +123 -0
- package/copy-react-native-dist.sh +38 -0
- package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.d.ts +6 -0
- package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js +1 -0
- package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js.map +1 -0
- package/dist/components/GestureCaptureWrapper/index.d.ts +1 -0
- package/dist/components/GestureCaptureWrapper/index.js +1 -0
- package/dist/components/GestureCaptureWrapper/index.js.map +1 -0
- package/dist/components/GestureCaptureWrapper.d.ts +6 -0
- package/dist/components/GestureCaptureWrapper.js +1 -0
- package/dist/components/GestureCaptureWrapper.js.map +1 -0
- package/dist/components/ScreenRecorderView/ScreenRecorderView.d.ts +5 -0
- package/dist/components/ScreenRecorderView/ScreenRecorderView.js +1 -0
- package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -0
- package/dist/components/ScreenRecorderView/index.d.ts +1 -0
- package/dist/components/ScreenRecorderView/index.js +1 -0
- package/dist/components/ScreenRecorderView/index.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -0
- package/dist/config/constants.d.ts +18 -0
- package/dist/config/constants.js +1 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/defaults.d.ts +4 -0
- package/dist/config/defaults.js +1 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/masking.d.ts +2 -30
- package/dist/config/masking.js +1 -1
- package/dist/config/masking.js.map +1 -1
- package/dist/config/session-recorder.d.ts +2 -0
- package/dist/config/session-recorder.js +1 -0
- package/dist/config/session-recorder.js.map +1 -0
- package/dist/config/validators.d.ts +10 -0
- package/dist/config/validators.js +1 -0
- package/dist/config/validators.js.map +1 -0
- package/dist/context/SessionRecorderContext.d.ts +12 -0
- package/dist/context/SessionRecorderContext.js +1 -0
- package/dist/context/SessionRecorderContext.js.map +1 -0
- package/dist/expo.d.ts +5 -9
- package/dist/expo.js +1 -1
- package/dist/expo.js.map +1 -1
- package/dist/index.d.ts +6 -10
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/otel/helpers.d.ts +45 -3
- package/dist/otel/helpers.js +1 -1
- package/dist/otel/helpers.js.map +1 -1
- package/dist/otel/index.d.ts +4 -25
- package/dist/otel/index.js +1 -1
- package/dist/otel/index.js.map +1 -1
- package/dist/otel/instrumentations/gestureInstrumentation.js +1 -1
- package/dist/otel/instrumentations/gestureInstrumentation.js.map +1 -1
- package/dist/otel/instrumentations/index.d.ts +3 -4
- package/dist/otel/instrumentations/index.js +1 -1
- package/dist/otel/instrumentations/index.js.map +1 -1
- package/dist/otel/instrumentations/reactNativeInstrumentation.js +1 -1
- package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +1 -1
- package/dist/otel/instrumentations/reactNavigationInstrumentation.d.ts +1 -0
- package/dist/otel/instrumentations/reactNavigationInstrumentation.js +1 -1
- package/dist/otel/instrumentations/reactNavigationInstrumentation.js.map +1 -1
- package/dist/patch/index.d.ts +1 -0
- package/dist/patch/index.js +1 -0
- package/dist/patch/index.js.map +1 -0
- package/dist/patch/xhr.d.ts +2 -0
- package/dist/patch/xhr.js +1 -0
- package/dist/patch/xhr.js.map +1 -0
- package/dist/recorder/eventExporter.d.ts +21 -0
- package/dist/recorder/eventExporter.js +1 -0
- package/dist/recorder/eventExporter.js.map +1 -0
- package/dist/recorder/gestureHandlerRecorder.d.ts +19 -0
- package/dist/recorder/gestureHandlerRecorder.js +1 -0
- package/dist/recorder/gestureHandlerRecorder.js.map +1 -0
- package/dist/recorder/gestureRecorder.d.ts +68 -11
- package/dist/recorder/gestureRecorder.js +1 -1
- package/dist/recorder/gestureRecorder.js.map +1 -1
- package/dist/recorder/index.d.ts +60 -6
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.js.map +1 -1
- package/dist/recorder/navigationTracker.js +1 -1
- package/dist/recorder/navigationTracker.js.map +1 -1
- package/dist/recorder/screenRecorder.d.ts +79 -10
- package/dist/recorder/screenRecorder.js +1 -1
- package/dist/recorder/screenRecorder.js.map +1 -1
- package/dist/services/api.service.d.ts +62 -10
- package/dist/services/api.service.js +1 -1
- package/dist/services/api.service.js.map +1 -1
- package/dist/services/storage.service.d.ts +23 -16
- package/dist/services/storage.service.js +1 -1
- package/dist/services/storage.service.js.map +1 -1
- package/dist/session-recorder.d.ts +166 -0
- package/dist/session-recorder.js +1 -0
- package/dist/session-recorder.js.map +1 -0
- package/dist/types/index.d.ts +15 -76
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/rrweb.d.ts +118 -0
- package/dist/types/rrweb.js +1 -0
- package/dist/types/rrweb.js.map +1 -0
- package/dist/types/session-recorder.d.ts +366 -0
- package/dist/types/session-recorder.js +1 -0
- package/dist/types/session-recorder.js.map +1 -0
- package/dist/types/session.d.ts +59 -0
- package/dist/types/session.js +1 -0
- package/dist/types/session.js.map +1 -0
- package/dist/utils/app-metadata.d.ts +16 -0
- package/dist/utils/app-metadata.js +1 -0
- package/dist/utils/app-metadata.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +112 -0
- package/dist/utils/logger.js +1 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/platform.d.ts +37 -0
- package/dist/utils/platform.js +1 -1
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/request-utils.d.ts +21 -0
- package/dist/utils/request-utils.js +1 -0
- package/dist/utils/request-utils.js.map +1 -0
- package/dist/utils/rrweb-events.d.ts +65 -0
- package/dist/utils/rrweb-events.js +1 -0
- package/dist/utils/rrweb-events.js.map +1 -0
- package/dist/utils/session.d.ts +5 -0
- package/dist/utils/session.js +1 -0
- package/dist/utils/session.js.map +1 -0
- package/dist/utils/time.d.ts +4 -0
- package/dist/utils/time.js +1 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/type-utils.d.ts +16 -0
- package/dist/utils/type-utils.js +1 -0
- package/dist/utils/type-utils.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/AUTO_METADATA_DETECTION.md +108 -0
- package/package.json +10 -9
- package/scripts/generate-app-metadata.js +173 -0
- package/src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx +86 -0
- package/src/components/GestureCaptureWrapper/index.ts +1 -0
- package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +72 -0
- package/src/components/ScreenRecorderView/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/config/constants.ts +60 -0
- package/src/config/defaults.ts +82 -0
- package/src/config/index.ts +6 -0
- package/src/config/masking.ts +10 -61
- package/src/config/session-recorder.ts +55 -0
- package/src/config/validators.ts +31 -0
- package/src/context/SessionRecorderContext.tsx +75 -0
- package/src/expo.ts +7 -37
- package/src/index.ts +14 -17
- package/src/otel/helpers.ts +265 -11
- package/src/otel/index.ts +37 -247
- package/src/otel/instrumentations/index.ts +82 -53
- package/src/patch/index.ts +1 -0
- package/src/patch/xhr.ts +142 -0
- package/src/recorder/eventExporter.ts +141 -0
- package/src/recorder/gestureRecorder.ts +194 -125
- package/src/recorder/index.ts +132 -24
- package/src/recorder/navigationTracker.ts +12 -10
- package/src/recorder/screenRecorder.ts +242 -155
- package/src/services/api.service.ts +170 -45
- package/src/services/storage.service.ts +102 -74
- package/src/session-recorder.ts +600 -0
- package/src/types/index.ts +19 -79
- package/src/types/session-recorder.ts +423 -0
- package/src/types/session.ts +65 -0
- package/src/utils/app-metadata.ts +31 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.ts +225 -0
- package/src/utils/platform.ts +321 -6
- package/src/utils/request-utils.ts +61 -0
- package/src/utils/rrweb-events.ts +309 -0
- package/src/utils/session.ts +18 -0
- package/src/utils/time.ts +17 -0
- package/src/utils/type-utils.ts +75 -0
- package/src/version.ts +1 -1
- package/dist/sessionRecorder.d.ts +0 -54
- package/dist/sessionRecorder.js +0 -1
- package/dist/sessionRecorder.js.map +0 -1
- package/examples/sample-expo-app/README.md +0 -142
- package/examples/sample-expo-app/app/(tabs)/_layout.tsx +0 -60
- package/examples/sample-expo-app/app/(tabs)/explore.tsx +0 -110
- package/examples/sample-expo-app/app/(tabs)/index.tsx +0 -125
- package/examples/sample-expo-app/app/(tabs)/posts.tsx +0 -96
- package/examples/sample-expo-app/app/(tabs)/users.tsx +0 -131
- package/examples/sample-expo-app/app/+not-found.tsx +0 -32
- package/examples/sample-expo-app/app/_layout.tsx +0 -53
- package/examples/sample-expo-app/app/post/[id].tsx +0 -199
- package/examples/sample-expo-app/app/user/[id].tsx +0 -270
- package/examples/sample-expo-app/app.json +0 -42
- package/examples/sample-expo-app/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/examples/sample-expo-app/assets/images/adaptive-icon.png +0 -0
- package/examples/sample-expo-app/assets/images/favicon.png +0 -0
- package/examples/sample-expo-app/assets/images/icon.png +0 -0
- package/examples/sample-expo-app/assets/images/partial-react-logo.png +0 -0
- package/examples/sample-expo-app/assets/images/react-logo.png +0 -0
- package/examples/sample-expo-app/assets/images/react-logo@2x.png +0 -0
- package/examples/sample-expo-app/assets/images/react-logo@3x.png +0 -0
- package/examples/sample-expo-app/assets/images/splash-icon.png +0 -0
- package/examples/sample-expo-app/components/Collapsible.tsx +0 -45
- package/examples/sample-expo-app/components/ErrorView.tsx +0 -52
- package/examples/sample-expo-app/components/ExternalLink.tsx +0 -24
- package/examples/sample-expo-app/components/HapticTab.tsx +0 -18
- package/examples/sample-expo-app/components/HelloWave.tsx +0 -40
- package/examples/sample-expo-app/components/LoadingSpinner.tsx +0 -34
- package/examples/sample-expo-app/components/ParallaxScrollView.tsx +0 -82
- package/examples/sample-expo-app/components/ThemedText.tsx +0 -60
- package/examples/sample-expo-app/components/ThemedView.tsx +0 -14
- package/examples/sample-expo-app/components/ui/IconSymbol.ios.tsx +0 -32
- package/examples/sample-expo-app/components/ui/IconSymbol.tsx +0 -41
- package/examples/sample-expo-app/components/ui/TabBarBackground.ios.tsx +0 -19
- package/examples/sample-expo-app/components/ui/TabBarBackground.tsx +0 -6
- package/examples/sample-expo-app/constants/Colors.ts +0 -26
- package/examples/sample-expo-app/eslint.config.js +0 -10
- package/examples/sample-expo-app/hooks/useApi.ts +0 -41
- package/examples/sample-expo-app/hooks/useColorScheme.ts +0 -1
- package/examples/sample-expo-app/hooks/useColorScheme.web.ts +0 -21
- package/examples/sample-expo-app/hooks/useThemeColor.ts +0 -21
- package/examples/sample-expo-app/metro.config.js +0 -26
- package/examples/sample-expo-app/package-lock.json +0 -26296
- package/examples/sample-expo-app/package.json +0 -59
- package/examples/sample-expo-app/scripts/reset-project.js +0 -112
- package/examples/sample-expo-app/services/api.ts +0 -98
- package/examples/sample-expo-app/tsconfig.json +0 -17
- package/examples/sample-expo-app/utils/navigation.ts +0 -19
- package/src/otel/instrumentations/gestureInstrumentation.ts +0 -141
- package/src/otel/instrumentations/reactNativeInstrumentation.ts +0 -164
- package/src/otel/instrumentations/reactNavigationInstrumentation.ts +0 -114
- package/src/sessionRecorder.ts +0 -367
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Tabs } from 'expo-router'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { Platform } from 'react-native'
|
|
4
|
-
|
|
5
|
-
import { HapticTab } from '@/components/HapticTab'
|
|
6
|
-
import { IconSymbol } from '@/components/ui/IconSymbol'
|
|
7
|
-
import TabBarBackground from '@/components/ui/TabBarBackground'
|
|
8
|
-
import { Colors } from '@/constants/Colors'
|
|
9
|
-
import { useColorScheme } from '@/hooks/useColorScheme'
|
|
10
|
-
|
|
11
|
-
export default function TabLayout() {
|
|
12
|
-
const colorScheme = useColorScheme()
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<Tabs
|
|
16
|
-
screenOptions={{
|
|
17
|
-
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
|
18
|
-
headerShown: false,
|
|
19
|
-
tabBarButton: HapticTab,
|
|
20
|
-
tabBarBackground: TabBarBackground,
|
|
21
|
-
tabBarStyle: Platform.select({
|
|
22
|
-
ios: {
|
|
23
|
-
// Use a transparent background on iOS to show the blur effect
|
|
24
|
-
position: 'absolute'
|
|
25
|
-
},
|
|
26
|
-
default: {}
|
|
27
|
-
})
|
|
28
|
-
}}
|
|
29
|
-
>
|
|
30
|
-
<Tabs.Screen
|
|
31
|
-
name='index'
|
|
32
|
-
options={{
|
|
33
|
-
title: 'Home',
|
|
34
|
-
tabBarIcon: ({ color }) => <IconSymbol size={28} name='house.fill' color={color} />
|
|
35
|
-
}}
|
|
36
|
-
/>
|
|
37
|
-
<Tabs.Screen
|
|
38
|
-
name='posts'
|
|
39
|
-
options={{
|
|
40
|
-
title: 'Posts',
|
|
41
|
-
tabBarIcon: ({ color }) => <IconSymbol size={28} name='doc.text.fill' color={color} />
|
|
42
|
-
}}
|
|
43
|
-
/>
|
|
44
|
-
<Tabs.Screen
|
|
45
|
-
name='users'
|
|
46
|
-
options={{
|
|
47
|
-
title: 'Users',
|
|
48
|
-
tabBarIcon: ({ color }) => <IconSymbol size={28} name='person.2.fill' color={color} />
|
|
49
|
-
}}
|
|
50
|
-
/>
|
|
51
|
-
<Tabs.Screen
|
|
52
|
-
name='explore'
|
|
53
|
-
options={{
|
|
54
|
-
title: 'Explore',
|
|
55
|
-
tabBarIcon: ({ color }) => <IconSymbol size={28} name='paperplane.fill' color={color} />
|
|
56
|
-
}}
|
|
57
|
-
/>
|
|
58
|
-
</Tabs>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { Image } from 'expo-image';
|
|
2
|
-
import { Platform, StyleSheet } from 'react-native';
|
|
3
|
-
|
|
4
|
-
import { Collapsible } from '@/components/Collapsible';
|
|
5
|
-
import { ExternalLink } from '@/components/ExternalLink';
|
|
6
|
-
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
|
7
|
-
import { ThemedText } from '@/components/ThemedText';
|
|
8
|
-
import { ThemedView } from '@/components/ThemedView';
|
|
9
|
-
import { IconSymbol } from '@/components/ui/IconSymbol';
|
|
10
|
-
|
|
11
|
-
export default function TabTwoScreen() {
|
|
12
|
-
return (
|
|
13
|
-
<ParallaxScrollView
|
|
14
|
-
headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
|
|
15
|
-
headerImage={
|
|
16
|
-
<IconSymbol
|
|
17
|
-
size={310}
|
|
18
|
-
color="#808080"
|
|
19
|
-
name="chevron.left.forwardslash.chevron.right"
|
|
20
|
-
style={styles.headerImage}
|
|
21
|
-
/>
|
|
22
|
-
}>
|
|
23
|
-
<ThemedView style={styles.titleContainer}>
|
|
24
|
-
<ThemedText type="title">Explore</ThemedText>
|
|
25
|
-
</ThemedView>
|
|
26
|
-
<ThemedText>This app includes example code to help you get started.</ThemedText>
|
|
27
|
-
<Collapsible title="File-based routing">
|
|
28
|
-
<ThemedText>
|
|
29
|
-
This app has two screens:{' '}
|
|
30
|
-
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
|
|
31
|
-
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
|
|
32
|
-
</ThemedText>
|
|
33
|
-
<ThemedText>
|
|
34
|
-
The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
|
|
35
|
-
sets up the tab navigator.
|
|
36
|
-
</ThemedText>
|
|
37
|
-
<ExternalLink href="https://docs.expo.dev/router/introduction">
|
|
38
|
-
<ThemedText type="link">Learn more</ThemedText>
|
|
39
|
-
</ExternalLink>
|
|
40
|
-
</Collapsible>
|
|
41
|
-
<Collapsible title="Android, iOS, and web support">
|
|
42
|
-
<ThemedText>
|
|
43
|
-
You can open this project on Android, iOS, and the web. To open the web version, press{' '}
|
|
44
|
-
<ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
|
|
45
|
-
</ThemedText>
|
|
46
|
-
</Collapsible>
|
|
47
|
-
<Collapsible title="Images">
|
|
48
|
-
<ThemedText>
|
|
49
|
-
For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
|
|
50
|
-
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
|
|
51
|
-
different screen densities
|
|
52
|
-
</ThemedText>
|
|
53
|
-
<Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
|
|
54
|
-
<ExternalLink href="https://reactnative.dev/docs/images">
|
|
55
|
-
<ThemedText type="link">Learn more</ThemedText>
|
|
56
|
-
</ExternalLink>
|
|
57
|
-
</Collapsible>
|
|
58
|
-
<Collapsible title="Custom fonts">
|
|
59
|
-
<ThemedText>
|
|
60
|
-
Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '}
|
|
61
|
-
<ThemedText style={{ fontFamily: 'SpaceMono' }}>
|
|
62
|
-
custom fonts such as this one.
|
|
63
|
-
</ThemedText>
|
|
64
|
-
</ThemedText>
|
|
65
|
-
<ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
|
|
66
|
-
<ThemedText type="link">Learn more</ThemedText>
|
|
67
|
-
</ExternalLink>
|
|
68
|
-
</Collapsible>
|
|
69
|
-
<Collapsible title="Light and dark mode components">
|
|
70
|
-
<ThemedText>
|
|
71
|
-
This template has light and dark mode support. The{' '}
|
|
72
|
-
<ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
|
|
73
|
-
what the user's current color scheme is, and so you can adjust UI colors accordingly.
|
|
74
|
-
</ThemedText>
|
|
75
|
-
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
|
|
76
|
-
<ThemedText type="link">Learn more</ThemedText>
|
|
77
|
-
</ExternalLink>
|
|
78
|
-
</Collapsible>
|
|
79
|
-
<Collapsible title="Animations">
|
|
80
|
-
<ThemedText>
|
|
81
|
-
This template includes an example of an animated component. The{' '}
|
|
82
|
-
<ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
|
|
83
|
-
the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '}
|
|
84
|
-
library to create a waving hand animation.
|
|
85
|
-
</ThemedText>
|
|
86
|
-
{Platform.select({
|
|
87
|
-
ios: (
|
|
88
|
-
<ThemedText>
|
|
89
|
-
The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
|
|
90
|
-
component provides a parallax effect for the header image.
|
|
91
|
-
</ThemedText>
|
|
92
|
-
),
|
|
93
|
-
})}
|
|
94
|
-
</Collapsible>
|
|
95
|
-
</ParallaxScrollView>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const styles = StyleSheet.create({
|
|
100
|
-
headerImage: {
|
|
101
|
-
color: '#808080',
|
|
102
|
-
bottom: -90,
|
|
103
|
-
left: -35,
|
|
104
|
-
position: 'absolute',
|
|
105
|
-
},
|
|
106
|
-
titleContainer: {
|
|
107
|
-
flexDirection: 'row',
|
|
108
|
-
gap: 8,
|
|
109
|
-
},
|
|
110
|
-
});
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { Image } from 'expo-image'
|
|
2
|
-
import { StyleSheet, TouchableOpacity } from 'react-native'
|
|
3
|
-
|
|
4
|
-
import { HelloWave } from '@/components/HelloWave'
|
|
5
|
-
import ParallaxScrollView from '@/components/ParallaxScrollView'
|
|
6
|
-
import { ThemedText } from '@/components/ThemedText'
|
|
7
|
-
import { ThemedView } from '@/components/ThemedView'
|
|
8
|
-
import { IconSymbol } from '@/components/ui/IconSymbol'
|
|
9
|
-
import { Colors } from '@/constants/Colors'
|
|
10
|
-
import { useColorScheme } from '@/hooks/useColorScheme'
|
|
11
|
-
|
|
12
|
-
export default function HomeScreen() {
|
|
13
|
-
const colorScheme = useColorScheme()
|
|
14
|
-
|
|
15
|
-
const handleNavigateToPosts = () => {
|
|
16
|
-
// Navigate to posts tab
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const handleNavigateToUsers = () => {
|
|
20
|
-
// Navigate to users tab
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<ParallaxScrollView
|
|
25
|
-
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
|
|
26
|
-
headerImage={<Image source={require('@/assets/images/partial-react-logo.png')} style={styles.reactLogo} />}
|
|
27
|
-
>
|
|
28
|
-
<ThemedView style={styles.titleContainer}>
|
|
29
|
-
<ThemedText type='title'>Welcome!</ThemedText>
|
|
30
|
-
<HelloWave />
|
|
31
|
-
</ThemedView>
|
|
32
|
-
|
|
33
|
-
<ThemedView style={styles.stepContainer}>
|
|
34
|
-
<ThemedText type='subtitle'>Enhanced Sample App</ThemedText>
|
|
35
|
-
<ThemedText>
|
|
36
|
-
This sample app now includes multiple pages, navigation, and API integration with JSONPlaceholder.
|
|
37
|
-
</ThemedText>
|
|
38
|
-
</ThemedView>
|
|
39
|
-
|
|
40
|
-
<ThemedView style={styles.featuresContainer}>
|
|
41
|
-
<ThemedText type='subtitle' style={styles.featuresTitle}>
|
|
42
|
-
Features
|
|
43
|
-
</ThemedText>
|
|
44
|
-
|
|
45
|
-
<TouchableOpacity style={styles.featureCard} onPress={handleNavigateToPosts} activeOpacity={0.7}>
|
|
46
|
-
<IconSymbol name='doc.text.fill' size={24} color={Colors[colorScheme ?? 'light'].tint} />
|
|
47
|
-
<ThemedView style={styles.featureContent}>
|
|
48
|
-
<ThemedText type='defaultSemiBold'>Posts</ThemedText>
|
|
49
|
-
<ThemedText style={styles.featureDescription}>Browse posts from JSONPlaceholder API with comments</ThemedText>
|
|
50
|
-
</ThemedView>
|
|
51
|
-
<IconSymbol name='chevron.right' size={16} color={Colors[colorScheme ?? 'light'].tint} />
|
|
52
|
-
</TouchableOpacity>
|
|
53
|
-
|
|
54
|
-
<TouchableOpacity style={styles.featureCard} onPress={handleNavigateToUsers} activeOpacity={0.7}>
|
|
55
|
-
<IconSymbol name='person.2.fill' size={24} color={Colors[colorScheme ?? 'light'].tint} />
|
|
56
|
-
<ThemedView style={styles.featureContent}>
|
|
57
|
-
<ThemedText type='defaultSemiBold'>Users</ThemedText>
|
|
58
|
-
<ThemedText style={styles.featureDescription}>View user profiles with their posts and details</ThemedText>
|
|
59
|
-
</ThemedView>
|
|
60
|
-
<IconSymbol name='chevron.right' size={16} color={Colors[colorScheme ?? 'light'].tint} />
|
|
61
|
-
</TouchableOpacity>
|
|
62
|
-
</ThemedView>
|
|
63
|
-
|
|
64
|
-
<ThemedView style={styles.stepContainer}>
|
|
65
|
-
<ThemedText type='subtitle'>Navigation</ThemedText>
|
|
66
|
-
<ThemedText>
|
|
67
|
-
Use the bottom tabs to navigate between different sections, or tap the feature cards above to explore the new
|
|
68
|
-
functionality.
|
|
69
|
-
</ThemedText>
|
|
70
|
-
</ThemedView>
|
|
71
|
-
|
|
72
|
-
<ThemedView style={styles.stepContainer}>
|
|
73
|
-
<ThemedText type='subtitle'>API Integration</ThemedText>
|
|
74
|
-
<ThemedText>
|
|
75
|
-
The app demonstrates real API calls to JSONPlaceholder with proper loading states, error handling, and data management.
|
|
76
|
-
</ThemedText>
|
|
77
|
-
</ThemedView>
|
|
78
|
-
</ParallaxScrollView>
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const styles = StyleSheet.create({
|
|
83
|
-
titleContainer: {
|
|
84
|
-
flexDirection: 'row',
|
|
85
|
-
alignItems: 'center',
|
|
86
|
-
gap: 8
|
|
87
|
-
},
|
|
88
|
-
stepContainer: {
|
|
89
|
-
gap: 8,
|
|
90
|
-
marginBottom: 8
|
|
91
|
-
},
|
|
92
|
-
featuresContainer: {
|
|
93
|
-
marginBottom: 16
|
|
94
|
-
},
|
|
95
|
-
featuresTitle: {
|
|
96
|
-
marginBottom: 12
|
|
97
|
-
},
|
|
98
|
-
featureCard: {
|
|
99
|
-
flexDirection: 'row',
|
|
100
|
-
alignItems: 'center',
|
|
101
|
-
padding: 16,
|
|
102
|
-
marginBottom: 12,
|
|
103
|
-
borderRadius: 12,
|
|
104
|
-
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
105
|
-
borderWidth: 1,
|
|
106
|
-
borderColor: 'rgba(255, 255, 255, 0.2)'
|
|
107
|
-
},
|
|
108
|
-
featureContent: {
|
|
109
|
-
flex: 1,
|
|
110
|
-
marginLeft: 12,
|
|
111
|
-
marginRight: 12
|
|
112
|
-
},
|
|
113
|
-
featureDescription: {
|
|
114
|
-
fontSize: 14,
|
|
115
|
-
opacity: 0.7,
|
|
116
|
-
marginTop: 2
|
|
117
|
-
},
|
|
118
|
-
reactLogo: {
|
|
119
|
-
height: 178,
|
|
120
|
-
width: 290,
|
|
121
|
-
bottom: 0,
|
|
122
|
-
left: 0,
|
|
123
|
-
position: 'absolute'
|
|
124
|
-
}
|
|
125
|
-
})
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { FlatList, StyleSheet, TouchableOpacity, RefreshControl } from 'react-native'
|
|
3
|
-
import { router } from 'expo-router'
|
|
4
|
-
import { ThemedView } from '@/components/ThemedView'
|
|
5
|
-
import { ThemedText } from '@/components/ThemedText'
|
|
6
|
-
import { LoadingSpinner } from '@/components/LoadingSpinner'
|
|
7
|
-
import { ErrorView } from '@/components/ErrorView'
|
|
8
|
-
import { useApi } from '@/hooks/useApi'
|
|
9
|
-
import { apiService, Post } from '@/services/api'
|
|
10
|
-
|
|
11
|
-
export default function PostsScreen() {
|
|
12
|
-
const { data: posts, loading, error, refetch } = useApi(() => apiService.getPosts())
|
|
13
|
-
|
|
14
|
-
const handlePostPress = (post: Post) => {
|
|
15
|
-
router.push(`/post/${post.id}`)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const renderPost = ({ item }: { item: Post }) => (
|
|
19
|
-
<TouchableOpacity style={styles.postCard} onPress={() => handlePostPress(item)} activeOpacity={0.7}>
|
|
20
|
-
<ThemedText type='subtitle' style={styles.postTitle}>
|
|
21
|
-
{item.title}
|
|
22
|
-
</ThemedText>
|
|
23
|
-
<ThemedText style={styles.postBody} numberOfLines={3}>
|
|
24
|
-
{item.body}
|
|
25
|
-
</ThemedText>
|
|
26
|
-
<ThemedText style={styles.postMeta}>
|
|
27
|
-
Post ID: {item.id} • User ID: {item.userId}
|
|
28
|
-
</ThemedText>
|
|
29
|
-
</TouchableOpacity>
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
if (loading) {
|
|
33
|
-
return <LoadingSpinner message='Loading posts...' />
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (error) {
|
|
37
|
-
return <ErrorView message={error} onRetry={refetch} />
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<ThemedView style={styles.container}>
|
|
42
|
-
<ThemedView style={styles.header}>
|
|
43
|
-
<ThemedText type='title'>Posts</ThemedText>
|
|
44
|
-
<ThemedText style={styles.subtitle}>Latest posts from JSONPlaceholder API</ThemedText>
|
|
45
|
-
</ThemedView>
|
|
46
|
-
|
|
47
|
-
<FlatList
|
|
48
|
-
data={posts}
|
|
49
|
-
renderItem={renderPost}
|
|
50
|
-
keyExtractor={(item) => item.id.toString()}
|
|
51
|
-
contentContainerStyle={styles.listContainer}
|
|
52
|
-
refreshControl={<RefreshControl refreshing={loading} onRefresh={refetch} />}
|
|
53
|
-
showsVerticalScrollIndicator={false}
|
|
54
|
-
/>
|
|
55
|
-
</ThemedView>
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const styles = StyleSheet.create({
|
|
60
|
-
container: {
|
|
61
|
-
flex: 1
|
|
62
|
-
},
|
|
63
|
-
header: {
|
|
64
|
-
padding: 20,
|
|
65
|
-
paddingTop: 60,
|
|
66
|
-
paddingBottom: 10
|
|
67
|
-
},
|
|
68
|
-
subtitle: {
|
|
69
|
-
marginTop: 4,
|
|
70
|
-
opacity: 0.7
|
|
71
|
-
},
|
|
72
|
-
listContainer: {
|
|
73
|
-
padding: 20,
|
|
74
|
-
paddingTop: 10
|
|
75
|
-
},
|
|
76
|
-
postCard: {
|
|
77
|
-
padding: 16,
|
|
78
|
-
marginBottom: 12,
|
|
79
|
-
borderRadius: 12,
|
|
80
|
-
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
81
|
-
borderWidth: 1,
|
|
82
|
-
borderColor: 'rgba(255, 255, 255, 0.2)'
|
|
83
|
-
},
|
|
84
|
-
postTitle: {
|
|
85
|
-
marginBottom: 8,
|
|
86
|
-
fontWeight: '600'
|
|
87
|
-
},
|
|
88
|
-
postBody: {
|
|
89
|
-
marginBottom: 12,
|
|
90
|
-
lineHeight: 20
|
|
91
|
-
},
|
|
92
|
-
postMeta: {
|
|
93
|
-
fontSize: 12,
|
|
94
|
-
opacity: 0.6
|
|
95
|
-
}
|
|
96
|
-
})
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { FlatList, StyleSheet, TouchableOpacity, RefreshControl } from 'react-native'
|
|
3
|
-
import { router } from 'expo-router'
|
|
4
|
-
import { ThemedView } from '@/components/ThemedView'
|
|
5
|
-
import { ThemedText } from '@/components/ThemedText'
|
|
6
|
-
import { LoadingSpinner } from '@/components/LoadingSpinner'
|
|
7
|
-
import { ErrorView } from '@/components/ErrorView'
|
|
8
|
-
import { IconSymbol } from '@/components/ui/IconSymbol'
|
|
9
|
-
import { useApi } from '@/hooks/useApi'
|
|
10
|
-
import { apiService, User } from '@/services/api'
|
|
11
|
-
import { Colors } from '@/constants/Colors'
|
|
12
|
-
import { useColorScheme } from '@/hooks/useColorScheme'
|
|
13
|
-
|
|
14
|
-
export default function UsersScreen() {
|
|
15
|
-
const { data: users, loading, error, refetch } = useApi(() => apiService.getUsers())
|
|
16
|
-
const colorScheme = useColorScheme()
|
|
17
|
-
|
|
18
|
-
const handleUserPress = (user: User) => {
|
|
19
|
-
router.push(`/user/${user.id}`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const renderUser = ({ item }: { item: User }) => (
|
|
23
|
-
<TouchableOpacity style={styles.userCard} onPress={() => handleUserPress(item)} activeOpacity={0.7}>
|
|
24
|
-
<ThemedView style={styles.userAvatar}>
|
|
25
|
-
<IconSymbol name='person.fill' size={24} color={Colors[colorScheme ?? 'light'].tint} />
|
|
26
|
-
</ThemedView>
|
|
27
|
-
|
|
28
|
-
<ThemedView style={styles.userInfo}>
|
|
29
|
-
<ThemedText type='subtitle' style={styles.userName}>
|
|
30
|
-
{item.name}
|
|
31
|
-
</ThemedText>
|
|
32
|
-
<ThemedText style={styles.userUsername}>@{item.username}</ThemedText>
|
|
33
|
-
<ThemedText style={styles.userEmail} numberOfLines={1}>
|
|
34
|
-
{item.email}
|
|
35
|
-
</ThemedText>
|
|
36
|
-
<ThemedText style={styles.userCompany}>{item.company.name}</ThemedText>
|
|
37
|
-
</ThemedView>
|
|
38
|
-
|
|
39
|
-
<IconSymbol name='chevron.right' size={16} color={Colors[colorScheme ?? 'light'].tint} style={styles.chevron} />
|
|
40
|
-
</TouchableOpacity>
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
if (loading) {
|
|
44
|
-
return <LoadingSpinner message='Loading users...' />
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (error) {
|
|
48
|
-
return <ErrorView message={error} onRetry={refetch} />
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<ThemedView style={styles.container}>
|
|
53
|
-
<ThemedView style={styles.header}>
|
|
54
|
-
<ThemedText type='title'>Users</ThemedText>
|
|
55
|
-
<ThemedText style={styles.subtitle}>Users from JSONPlaceholder API</ThemedText>
|
|
56
|
-
</ThemedView>
|
|
57
|
-
|
|
58
|
-
<FlatList
|
|
59
|
-
data={users}
|
|
60
|
-
renderItem={renderUser}
|
|
61
|
-
keyExtractor={(item) => item.id.toString()}
|
|
62
|
-
contentContainerStyle={styles.listContainer}
|
|
63
|
-
refreshControl={<RefreshControl refreshing={loading} onRefresh={refetch} />}
|
|
64
|
-
showsVerticalScrollIndicator={false}
|
|
65
|
-
/>
|
|
66
|
-
</ThemedView>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const styles = StyleSheet.create({
|
|
71
|
-
container: {
|
|
72
|
-
flex: 1
|
|
73
|
-
},
|
|
74
|
-
header: {
|
|
75
|
-
padding: 20,
|
|
76
|
-
paddingTop: 60,
|
|
77
|
-
paddingBottom: 10
|
|
78
|
-
},
|
|
79
|
-
subtitle: {
|
|
80
|
-
marginTop: 4,
|
|
81
|
-
opacity: 0.7
|
|
82
|
-
},
|
|
83
|
-
listContainer: {
|
|
84
|
-
padding: 20,
|
|
85
|
-
paddingTop: 10
|
|
86
|
-
},
|
|
87
|
-
userCard: {
|
|
88
|
-
flexDirection: 'row',
|
|
89
|
-
alignItems: 'center',
|
|
90
|
-
padding: 16,
|
|
91
|
-
marginBottom: 12,
|
|
92
|
-
borderRadius: 12,
|
|
93
|
-
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
94
|
-
borderWidth: 1,
|
|
95
|
-
borderColor: 'rgba(255, 255, 255, 0.2)'
|
|
96
|
-
},
|
|
97
|
-
userAvatar: {
|
|
98
|
-
width: 48,
|
|
99
|
-
height: 48,
|
|
100
|
-
borderRadius: 24,
|
|
101
|
-
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
|
102
|
-
justifyContent: 'center',
|
|
103
|
-
alignItems: 'center',
|
|
104
|
-
marginRight: 12
|
|
105
|
-
},
|
|
106
|
-
userInfo: {
|
|
107
|
-
flex: 1
|
|
108
|
-
},
|
|
109
|
-
userName: {
|
|
110
|
-
marginBottom: 2,
|
|
111
|
-
fontWeight: '600'
|
|
112
|
-
},
|
|
113
|
-
userUsername: {
|
|
114
|
-
fontSize: 14,
|
|
115
|
-
opacity: 0.7,
|
|
116
|
-
marginBottom: 4
|
|
117
|
-
},
|
|
118
|
-
userEmail: {
|
|
119
|
-
fontSize: 12,
|
|
120
|
-
opacity: 0.6,
|
|
121
|
-
marginBottom: 2
|
|
122
|
-
},
|
|
123
|
-
userCompany: {
|
|
124
|
-
fontSize: 12,
|
|
125
|
-
opacity: 0.8,
|
|
126
|
-
fontStyle: 'italic'
|
|
127
|
-
},
|
|
128
|
-
chevron: {
|
|
129
|
-
opacity: 0.5
|
|
130
|
-
}
|
|
131
|
-
})
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Link, Stack } from 'expo-router';
|
|
2
|
-
import { StyleSheet } from 'react-native';
|
|
3
|
-
|
|
4
|
-
import { ThemedText } from '@/components/ThemedText';
|
|
5
|
-
import { ThemedView } from '@/components/ThemedView';
|
|
6
|
-
|
|
7
|
-
export default function NotFoundScreen() {
|
|
8
|
-
return (
|
|
9
|
-
<>
|
|
10
|
-
<Stack.Screen options={{ title: 'Oops!' }} />
|
|
11
|
-
<ThemedView style={styles.container}>
|
|
12
|
-
<ThemedText type="title">This screen does not exist.</ThemedText>
|
|
13
|
-
<Link href="/" style={styles.link}>
|
|
14
|
-
<ThemedText type="link">Go to home screen!</ThemedText>
|
|
15
|
-
</Link>
|
|
16
|
-
</ThemedView>
|
|
17
|
-
</>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const styles = StyleSheet.create({
|
|
22
|
-
container: {
|
|
23
|
-
flex: 1,
|
|
24
|
-
alignItems: 'center',
|
|
25
|
-
justifyContent: 'center',
|
|
26
|
-
padding: 20,
|
|
27
|
-
},
|
|
28
|
-
link: {
|
|
29
|
-
marginTop: 15,
|
|
30
|
-
paddingVertical: 15,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'
|
|
2
|
-
import { useFonts } from 'expo-font'
|
|
3
|
-
import { Stack } from 'expo-router'
|
|
4
|
-
import { StatusBar } from 'expo-status-bar'
|
|
5
|
-
import 'react-native-reanimated'
|
|
6
|
-
|
|
7
|
-
import { useColorScheme } from '@/hooks/useColorScheme'
|
|
8
|
-
import SessionRecorder from '@multiplayer-app/session-recorder-react-native'
|
|
9
|
-
|
|
10
|
-
SessionRecorder.init({
|
|
11
|
-
version: '0.0.1',
|
|
12
|
-
application: 'multiplayer-web-app',
|
|
13
|
-
environment: 'development',
|
|
14
|
-
apiKey:
|
|
15
|
-
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpbnRlZ3JhdGlvbiI6IjY4NGZlMDljMjA0NmYwYjM0ZjU5ZDNjYyIsIndvcmtzcGFjZSI6IjY4NGMzYmYwYjQ2MGUzMmY3YWJmZjRlMSIsInByb2plY3QiOiI2ODRjM2M0MmI0NjBlMzJmN2FiZmY1YzgiLCJ0eXBlIjoiT1RFTCIsImlhdCI6MTc1MDA2NTMwOH0.F15dW5RUHtq4-e2FUZD_vK0FJ5USs8SRFbnPYO_0XVk',
|
|
16
|
-
apiBaseUrl: 'http://localhost',
|
|
17
|
-
exporterEndpoint: 'http://localhost/v1/traces',
|
|
18
|
-
showWidget: true,
|
|
19
|
-
ignoreUrls: [
|
|
20
|
-
/posthog\.com.*/,
|
|
21
|
-
/https:\/\/bam\.nr-data\.net\/.*/,
|
|
22
|
-
/https:\/\/cdn\.jsdelivr\.net\/.*/,
|
|
23
|
-
/https:\/\/pixel\.source\.app\/.*/
|
|
24
|
-
]
|
|
25
|
-
// propagateTraceHeaderCorsUrls: new RegExp(
|
|
26
|
-
// `${process.env.REACT_APP_API_BASE_URL}\.*`,
|
|
27
|
-
// "i"
|
|
28
|
-
// ),
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
export default function RootLayout() {
|
|
32
|
-
const colorScheme = useColorScheme()
|
|
33
|
-
const [loaded] = useFonts({
|
|
34
|
-
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf')
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
if (!loaded) {
|
|
38
|
-
// Async font loading only occurs in development.
|
|
39
|
-
return null
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
|
44
|
-
<Stack>
|
|
45
|
-
<Stack.Screen name='(tabs)' options={{ headerShown: false }} />
|
|
46
|
-
<Stack.Screen name='post/[id]' options={{ headerShown: false }} />
|
|
47
|
-
<Stack.Screen name='user/[id]' options={{ headerShown: false }} />
|
|
48
|
-
<Stack.Screen name='+not-found' />
|
|
49
|
-
</Stack>
|
|
50
|
-
<StatusBar style='auto' />
|
|
51
|
-
</ThemeProvider>
|
|
52
|
-
)
|
|
53
|
-
}
|