@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.
Files changed (234) hide show
  1. package/RRWEB_INTEGRATION.md +336 -0
  2. package/VIEWSHOT_INTEGRATION_TEST.md +123 -0
  3. package/copy-react-native-dist.sh +38 -0
  4. package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.d.ts +6 -0
  5. package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js +1 -0
  6. package/dist/components/GestureCaptureWrapper/GestureCaptureWrapper.js.map +1 -0
  7. package/dist/components/GestureCaptureWrapper/index.d.ts +1 -0
  8. package/dist/components/GestureCaptureWrapper/index.js +1 -0
  9. package/dist/components/GestureCaptureWrapper/index.js.map +1 -0
  10. package/dist/components/GestureCaptureWrapper.d.ts +6 -0
  11. package/dist/components/GestureCaptureWrapper.js +1 -0
  12. package/dist/components/GestureCaptureWrapper.js.map +1 -0
  13. package/dist/components/ScreenRecorderView/ScreenRecorderView.d.ts +5 -0
  14. package/dist/components/ScreenRecorderView/ScreenRecorderView.js +1 -0
  15. package/dist/components/ScreenRecorderView/ScreenRecorderView.js.map +1 -0
  16. package/dist/components/ScreenRecorderView/index.d.ts +1 -0
  17. package/dist/components/ScreenRecorderView/index.js +1 -0
  18. package/dist/components/ScreenRecorderView/index.js.map +1 -0
  19. package/dist/components/index.d.ts +1 -0
  20. package/dist/components/index.js +1 -0
  21. package/dist/components/index.js.map +1 -0
  22. package/dist/config/constants.d.ts +18 -0
  23. package/dist/config/constants.js +1 -0
  24. package/dist/config/constants.js.map +1 -0
  25. package/dist/config/defaults.d.ts +4 -0
  26. package/dist/config/defaults.js +1 -0
  27. package/dist/config/defaults.js.map +1 -0
  28. package/dist/config/index.d.ts +5 -0
  29. package/dist/config/index.js +1 -0
  30. package/dist/config/index.js.map +1 -0
  31. package/dist/config/masking.d.ts +2 -30
  32. package/dist/config/masking.js +1 -1
  33. package/dist/config/masking.js.map +1 -1
  34. package/dist/config/session-recorder.d.ts +2 -0
  35. package/dist/config/session-recorder.js +1 -0
  36. package/dist/config/session-recorder.js.map +1 -0
  37. package/dist/config/validators.d.ts +10 -0
  38. package/dist/config/validators.js +1 -0
  39. package/dist/config/validators.js.map +1 -0
  40. package/dist/context/SessionRecorderContext.d.ts +12 -0
  41. package/dist/context/SessionRecorderContext.js +1 -0
  42. package/dist/context/SessionRecorderContext.js.map +1 -0
  43. package/dist/expo.d.ts +5 -9
  44. package/dist/expo.js +1 -1
  45. package/dist/expo.js.map +1 -1
  46. package/dist/index.d.ts +6 -10
  47. package/dist/index.js +1 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/otel/helpers.d.ts +45 -3
  50. package/dist/otel/helpers.js +1 -1
  51. package/dist/otel/helpers.js.map +1 -1
  52. package/dist/otel/index.d.ts +4 -25
  53. package/dist/otel/index.js +1 -1
  54. package/dist/otel/index.js.map +1 -1
  55. package/dist/otel/instrumentations/gestureInstrumentation.js +1 -1
  56. package/dist/otel/instrumentations/gestureInstrumentation.js.map +1 -1
  57. package/dist/otel/instrumentations/index.d.ts +3 -4
  58. package/dist/otel/instrumentations/index.js +1 -1
  59. package/dist/otel/instrumentations/index.js.map +1 -1
  60. package/dist/otel/instrumentations/reactNativeInstrumentation.js +1 -1
  61. package/dist/otel/instrumentations/reactNativeInstrumentation.js.map +1 -1
  62. package/dist/otel/instrumentations/reactNavigationInstrumentation.d.ts +1 -0
  63. package/dist/otel/instrumentations/reactNavigationInstrumentation.js +1 -1
  64. package/dist/otel/instrumentations/reactNavigationInstrumentation.js.map +1 -1
  65. package/dist/patch/index.d.ts +1 -0
  66. package/dist/patch/index.js +1 -0
  67. package/dist/patch/index.js.map +1 -0
  68. package/dist/patch/xhr.d.ts +2 -0
  69. package/dist/patch/xhr.js +1 -0
  70. package/dist/patch/xhr.js.map +1 -0
  71. package/dist/recorder/eventExporter.d.ts +21 -0
  72. package/dist/recorder/eventExporter.js +1 -0
  73. package/dist/recorder/eventExporter.js.map +1 -0
  74. package/dist/recorder/gestureHandlerRecorder.d.ts +19 -0
  75. package/dist/recorder/gestureHandlerRecorder.js +1 -0
  76. package/dist/recorder/gestureHandlerRecorder.js.map +1 -0
  77. package/dist/recorder/gestureRecorder.d.ts +68 -11
  78. package/dist/recorder/gestureRecorder.js +1 -1
  79. package/dist/recorder/gestureRecorder.js.map +1 -1
  80. package/dist/recorder/index.d.ts +60 -6
  81. package/dist/recorder/index.js +1 -1
  82. package/dist/recorder/index.js.map +1 -1
  83. package/dist/recorder/navigationTracker.js +1 -1
  84. package/dist/recorder/navigationTracker.js.map +1 -1
  85. package/dist/recorder/screenRecorder.d.ts +79 -10
  86. package/dist/recorder/screenRecorder.js +1 -1
  87. package/dist/recorder/screenRecorder.js.map +1 -1
  88. package/dist/services/api.service.d.ts +62 -10
  89. package/dist/services/api.service.js +1 -1
  90. package/dist/services/api.service.js.map +1 -1
  91. package/dist/services/storage.service.d.ts +23 -16
  92. package/dist/services/storage.service.js +1 -1
  93. package/dist/services/storage.service.js.map +1 -1
  94. package/dist/session-recorder.d.ts +166 -0
  95. package/dist/session-recorder.js +1 -0
  96. package/dist/session-recorder.js.map +1 -0
  97. package/dist/types/index.d.ts +15 -76
  98. package/dist/types/index.js +1 -1
  99. package/dist/types/index.js.map +1 -1
  100. package/dist/types/rrweb.d.ts +118 -0
  101. package/dist/types/rrweb.js +1 -0
  102. package/dist/types/rrweb.js.map +1 -0
  103. package/dist/types/session-recorder.d.ts +366 -0
  104. package/dist/types/session-recorder.js +1 -0
  105. package/dist/types/session-recorder.js.map +1 -0
  106. package/dist/types/session.d.ts +59 -0
  107. package/dist/types/session.js +1 -0
  108. package/dist/types/session.js.map +1 -0
  109. package/dist/utils/app-metadata.d.ts +16 -0
  110. package/dist/utils/app-metadata.js +1 -0
  111. package/dist/utils/app-metadata.js.map +1 -0
  112. package/dist/utils/index.d.ts +7 -0
  113. package/dist/utils/index.js +1 -0
  114. package/dist/utils/index.js.map +1 -0
  115. package/dist/utils/logger.d.ts +112 -0
  116. package/dist/utils/logger.js +1 -0
  117. package/dist/utils/logger.js.map +1 -0
  118. package/dist/utils/platform.d.ts +37 -0
  119. package/dist/utils/platform.js +1 -1
  120. package/dist/utils/platform.js.map +1 -1
  121. package/dist/utils/request-utils.d.ts +21 -0
  122. package/dist/utils/request-utils.js +1 -0
  123. package/dist/utils/request-utils.js.map +1 -0
  124. package/dist/utils/rrweb-events.d.ts +65 -0
  125. package/dist/utils/rrweb-events.js +1 -0
  126. package/dist/utils/rrweb-events.js.map +1 -0
  127. package/dist/utils/session.d.ts +5 -0
  128. package/dist/utils/session.js +1 -0
  129. package/dist/utils/session.js.map +1 -0
  130. package/dist/utils/time.d.ts +4 -0
  131. package/dist/utils/time.js +1 -0
  132. package/dist/utils/time.js.map +1 -0
  133. package/dist/utils/type-utils.d.ts +16 -0
  134. package/dist/utils/type-utils.js +1 -0
  135. package/dist/utils/type-utils.js.map +1 -0
  136. package/dist/version.d.ts +1 -1
  137. package/dist/version.js +1 -1
  138. package/dist/version.js.map +1 -1
  139. package/docs/AUTO_METADATA_DETECTION.md +108 -0
  140. package/package.json +10 -9
  141. package/scripts/generate-app-metadata.js +173 -0
  142. package/src/components/GestureCaptureWrapper/GestureCaptureWrapper.tsx +86 -0
  143. package/src/components/GestureCaptureWrapper/index.ts +1 -0
  144. package/src/components/ScreenRecorderView/ScreenRecorderView.tsx +72 -0
  145. package/src/components/ScreenRecorderView/index.ts +1 -0
  146. package/src/components/index.ts +1 -0
  147. package/src/config/constants.ts +60 -0
  148. package/src/config/defaults.ts +82 -0
  149. package/src/config/index.ts +6 -0
  150. package/src/config/masking.ts +10 -61
  151. package/src/config/session-recorder.ts +55 -0
  152. package/src/config/validators.ts +31 -0
  153. package/src/context/SessionRecorderContext.tsx +75 -0
  154. package/src/expo.ts +7 -37
  155. package/src/index.ts +14 -17
  156. package/src/otel/helpers.ts +265 -11
  157. package/src/otel/index.ts +37 -247
  158. package/src/otel/instrumentations/index.ts +82 -53
  159. package/src/patch/index.ts +1 -0
  160. package/src/patch/xhr.ts +142 -0
  161. package/src/recorder/eventExporter.ts +141 -0
  162. package/src/recorder/gestureRecorder.ts +194 -125
  163. package/src/recorder/index.ts +132 -24
  164. package/src/recorder/navigationTracker.ts +12 -10
  165. package/src/recorder/screenRecorder.ts +242 -155
  166. package/src/services/api.service.ts +170 -45
  167. package/src/services/storage.service.ts +102 -74
  168. package/src/session-recorder.ts +600 -0
  169. package/src/types/index.ts +19 -79
  170. package/src/types/session-recorder.ts +423 -0
  171. package/src/types/session.ts +65 -0
  172. package/src/utils/app-metadata.ts +31 -0
  173. package/src/utils/index.ts +8 -0
  174. package/src/utils/logger.ts +225 -0
  175. package/src/utils/platform.ts +321 -6
  176. package/src/utils/request-utils.ts +61 -0
  177. package/src/utils/rrweb-events.ts +309 -0
  178. package/src/utils/session.ts +18 -0
  179. package/src/utils/time.ts +17 -0
  180. package/src/utils/type-utils.ts +75 -0
  181. package/src/version.ts +1 -1
  182. package/dist/sessionRecorder.d.ts +0 -54
  183. package/dist/sessionRecorder.js +0 -1
  184. package/dist/sessionRecorder.js.map +0 -1
  185. package/examples/sample-expo-app/README.md +0 -142
  186. package/examples/sample-expo-app/app/(tabs)/_layout.tsx +0 -60
  187. package/examples/sample-expo-app/app/(tabs)/explore.tsx +0 -110
  188. package/examples/sample-expo-app/app/(tabs)/index.tsx +0 -125
  189. package/examples/sample-expo-app/app/(tabs)/posts.tsx +0 -96
  190. package/examples/sample-expo-app/app/(tabs)/users.tsx +0 -131
  191. package/examples/sample-expo-app/app/+not-found.tsx +0 -32
  192. package/examples/sample-expo-app/app/_layout.tsx +0 -53
  193. package/examples/sample-expo-app/app/post/[id].tsx +0 -199
  194. package/examples/sample-expo-app/app/user/[id].tsx +0 -270
  195. package/examples/sample-expo-app/app.json +0 -42
  196. package/examples/sample-expo-app/assets/fonts/SpaceMono-Regular.ttf +0 -0
  197. package/examples/sample-expo-app/assets/images/adaptive-icon.png +0 -0
  198. package/examples/sample-expo-app/assets/images/favicon.png +0 -0
  199. package/examples/sample-expo-app/assets/images/icon.png +0 -0
  200. package/examples/sample-expo-app/assets/images/partial-react-logo.png +0 -0
  201. package/examples/sample-expo-app/assets/images/react-logo.png +0 -0
  202. package/examples/sample-expo-app/assets/images/react-logo@2x.png +0 -0
  203. package/examples/sample-expo-app/assets/images/react-logo@3x.png +0 -0
  204. package/examples/sample-expo-app/assets/images/splash-icon.png +0 -0
  205. package/examples/sample-expo-app/components/Collapsible.tsx +0 -45
  206. package/examples/sample-expo-app/components/ErrorView.tsx +0 -52
  207. package/examples/sample-expo-app/components/ExternalLink.tsx +0 -24
  208. package/examples/sample-expo-app/components/HapticTab.tsx +0 -18
  209. package/examples/sample-expo-app/components/HelloWave.tsx +0 -40
  210. package/examples/sample-expo-app/components/LoadingSpinner.tsx +0 -34
  211. package/examples/sample-expo-app/components/ParallaxScrollView.tsx +0 -82
  212. package/examples/sample-expo-app/components/ThemedText.tsx +0 -60
  213. package/examples/sample-expo-app/components/ThemedView.tsx +0 -14
  214. package/examples/sample-expo-app/components/ui/IconSymbol.ios.tsx +0 -32
  215. package/examples/sample-expo-app/components/ui/IconSymbol.tsx +0 -41
  216. package/examples/sample-expo-app/components/ui/TabBarBackground.ios.tsx +0 -19
  217. package/examples/sample-expo-app/components/ui/TabBarBackground.tsx +0 -6
  218. package/examples/sample-expo-app/constants/Colors.ts +0 -26
  219. package/examples/sample-expo-app/eslint.config.js +0 -10
  220. package/examples/sample-expo-app/hooks/useApi.ts +0 -41
  221. package/examples/sample-expo-app/hooks/useColorScheme.ts +0 -1
  222. package/examples/sample-expo-app/hooks/useColorScheme.web.ts +0 -21
  223. package/examples/sample-expo-app/hooks/useThemeColor.ts +0 -21
  224. package/examples/sample-expo-app/metro.config.js +0 -26
  225. package/examples/sample-expo-app/package-lock.json +0 -26296
  226. package/examples/sample-expo-app/package.json +0 -59
  227. package/examples/sample-expo-app/scripts/reset-project.js +0 -112
  228. package/examples/sample-expo-app/services/api.ts +0 -98
  229. package/examples/sample-expo-app/tsconfig.json +0 -17
  230. package/examples/sample-expo-app/utils/navigation.ts +0 -19
  231. package/src/otel/instrumentations/gestureInstrumentation.ts +0 -141
  232. package/src/otel/instrumentations/reactNativeInstrumentation.ts +0 -164
  233. package/src/otel/instrumentations/reactNavigationInstrumentation.ts +0 -114
  234. 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&apos;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
- }