An ATproto social media client -- with an independent Appview.

Add basic analytics (#89)

* Add basic analytics

* Fix: add mock for analytics

authored by

Paul Frazee and committed by
GitHub
21f5f4de f36c9565

+190 -14
+1
android/app/src/main/AndroidManifest.xml
··· 4 <uses-permission android:name="android.permission.INTERNET" /> 5 <uses-permission android:name="android.permission.CAMERA"/> 6 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 7 8 <application 9 android:name=".MainApplication"
··· 4 <uses-permission android:name="android.permission.INTERNET" /> 5 <uses-permission android:name="android.permission.CAMERA"/> 6 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 7 + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 8 9 <application 10 android:name=".MainApplication"
+13
ios/Podfile.lock
··· 393 - React-RCTImage 394 - RNSVG (12.5.0): 395 - React-Core 396 - Swime (3.0.6) 397 - TOCropViewController (2.6.1) 398 - Yoga (1.14.0) ··· 453 - RNReanimated (from `../node_modules/react-native-reanimated`) 454 - RNScreens (from `../node_modules/react-native-screens`) 455 - RNSVG (from `../node_modules/react-native-svg`) 456 - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 457 458 SPEC REPOS: ··· 569 :path: "../node_modules/react-native-screens" 570 RNSVG: 571 :path: "../node_modules/react-native-svg" 572 Yoga: 573 :path: "../node_modules/react-native/ReactCommon/yoga" 574 ··· 628 RNReanimated: d8d9d3d3801bda5e35e85cdffc871577d044dc2e 629 RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d 630 RNSVG: 6adc5c52d2488a476248413064b7f2832e639057 631 Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b 632 TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 633 Yoga: c618b544ff8bd8865cdca602f00cbcdb92fd6d31
··· 393 - React-RCTImage 394 - RNSVG (12.5.0): 395 - React-Core 396 + - segment-analytics-react-native (2.10.1): 397 + - React-Core 398 + - sovran-react-native 399 + - sovran-react-native (0.4.5): 400 + - React-Core 401 - Swime (3.0.6) 402 - TOCropViewController (2.6.1) 403 - Yoga (1.14.0) ··· 458 - RNReanimated (from `../node_modules/react-native-reanimated`) 459 - RNScreens (from `../node_modules/react-native-screens`) 460 - RNSVG (from `../node_modules/react-native-svg`) 461 + - "segment-analytics-react-native (from `../node_modules/@segment/analytics-react-native`)" 462 + - "sovran-react-native (from `../node_modules/@segment/sovran-react-native`)" 463 - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 464 465 SPEC REPOS: ··· 576 :path: "../node_modules/react-native-screens" 577 RNSVG: 578 :path: "../node_modules/react-native-svg" 579 + segment-analytics-react-native: 580 + :path: "../node_modules/@segment/analytics-react-native" 581 + sovran-react-native: 582 + :path: "../node_modules/@segment/sovran-react-native" 583 Yoga: 584 :path: "../node_modules/react-native/ReactCommon/yoga" 585 ··· 639 RNReanimated: d8d9d3d3801bda5e35e85cdffc871577d044dc2e 640 RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d 641 RNSVG: 6adc5c52d2488a476248413064b7f2832e639057 642 + segment-analytics-react-native: cb097e393c3560a0d4cfd877044293e37b0050d9 643 + sovran-react-native: fd3dc8f1a4b14acdc4ad25fc6b4ac4f52a2a2a15 644 Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b 645 TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 646 Yoga: c618b544ff8bd8865cdca602f00cbcdb92fd6d31
+15
jest/jestSetup.js
··· 40 ...jest.requireActual('react-native-tab-view'), 41 TabView: mockedView, 42 }))
··· 40 ...jest.requireActual('react-native-tab-view'), 41 TabView: mockedView, 42 })) 43 + 44 + jest.mock('@segment/analytics-react-native', () => ({ 45 + createClient: () => ({ 46 + add: jest.fn(), 47 + }), 48 + useAnalytics: () => ({ 49 + track: jest.fn(), 50 + identify: jest.fn(), 51 + reset: jest.fn(), 52 + group: jest.fn(), 53 + screen: jest.fn(), 54 + alias: jest.fn(), 55 + flush: jest.fn(), 56 + }), 57 + }))
+2
package.json
··· 29 "@react-native-camera-roll/camera-roll": "^5.1.0", 30 "@react-native-clipboard/clipboard": "^1.10.0", 31 "@react-native-community/blur": "^4.3.0", 32 "@zxing/text-encoding": "^0.9.0", 33 "base64-js": "^1.5.1", 34 "email-validator": "^2.0.4",
··· 29 "@react-native-camera-roll/camera-roll": "^5.1.0", 30 "@react-native-clipboard/clipboard": "^1.10.0", 31 "@react-native-community/blur": "^4.3.0", 32 + "@segment/analytics-react-native": "^2.10.1", 33 + "@segment/sovran-react-native": "^0.4.5", 34 "@zxing/text-encoding": "^0.9.0", 35 "base64-js": "^1.5.1", 36 "email-validator": "^2.0.4",
+21 -7
src/App.native.tsx
··· 6 import SplashScreen from 'react-native-splash-screen' 7 import {SafeAreaProvider} from 'react-native-safe-area-context' 8 import {observer} from 'mobx-react-lite' 9 import {ThemeProvider} from './view/lib/ThemeContext' 10 import * as view from './view/index' 11 import {RootStoreModel, setupState, RootStoreProvider} from './state' ··· 16 const [rootStore, setRootStore] = useState<RootStoreModel | undefined>( 17 undefined, 18 ) 19 20 // init 21 useEffect(() => { 22 view.setup() 23 setupState().then(store => { 24 setRootStore(store) 25 SplashScreen.hide() ··· 42 return ( 43 <GestureHandlerRootView style={s.h100pct}> 44 <RootSiblingParent> 45 - <RootStoreProvider value={rootStore}> 46 - <ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}> 47 - <SafeAreaProvider> 48 - <MobileShell /> 49 - </SafeAreaProvider> 50 - </ThemeProvider> 51 - </RootStoreProvider> 52 </RootSiblingParent> 53 </GestureHandlerRootView> 54 )
··· 6 import SplashScreen from 'react-native-splash-screen' 7 import {SafeAreaProvider} from 'react-native-safe-area-context' 8 import {observer} from 'mobx-react-lite' 9 + import { 10 + createClient, 11 + SegmentClient, 12 + AnalyticsProvider, 13 + } from '@segment/analytics-react-native' 14 import {ThemeProvider} from './view/lib/ThemeContext' 15 import * as view from './view/index' 16 import {RootStoreModel, setupState, RootStoreProvider} from './state' ··· 21 const [rootStore, setRootStore] = useState<RootStoreModel | undefined>( 22 undefined, 23 ) 24 + const [segment, setSegment] = useState<SegmentClient | undefined>(undefined) 25 26 // init 27 useEffect(() => { 28 view.setup() 29 + setSegment( 30 + createClient({ 31 + writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI', 32 + trackAppLifecycleEvents: true, 33 + }), 34 + ) 35 setupState().then(store => { 36 setRootStore(store) 37 SplashScreen.hide() ··· 54 return ( 55 <GestureHandlerRootView style={s.h100pct}> 56 <RootSiblingParent> 57 + <AnalyticsProvider client={segment}> 58 + <RootStoreProvider value={rootStore}> 59 + <ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}> 60 + <SafeAreaProvider> 61 + <MobileShell /> 62 + </SafeAreaProvider> 63 + </ThemeProvider> 64 + </RootStoreProvider> 65 + </AnalyticsProvider> 66 </RootSiblingParent> 67 </GestureHandlerRootView> 68 )
+5
src/view/com/composer/ComposePost.tsx
··· 17 } from '@mattermost/react-native-paste-input' 18 import LinearGradient from 'react-native-linear-gradient' 19 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 20 import {UserAutocompleteViewModel} from '../../../state/models/user-autocomplete-view' 21 import {Autocomplete} from './Autocomplete' 22 import {ExternalEmbed} from './ExternalEmbed' ··· 59 onPost?: ComposerOpts['onPost'] 60 onClose: () => void 61 }) { 62 const pal = usePalette('default') 63 const store = useStores() 64 const textInput = useRef<PasteInputRef>(null) ··· 252 autocompleteView.knownHandles, 253 setProcessingState, 254 ) 255 } catch (e: any) { 256 setError(cleanError(e.message)) 257 setIsProcessing(false)
··· 17 } from '@mattermost/react-native-paste-input' 18 import LinearGradient from 'react-native-linear-gradient' 19 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 20 + import {useAnalytics} from '@segment/analytics-react-native' 21 import {UserAutocompleteViewModel} from '../../../state/models/user-autocomplete-view' 22 import {Autocomplete} from './Autocomplete' 23 import {ExternalEmbed} from './ExternalEmbed' ··· 60 onPost?: ComposerOpts['onPost'] 61 onClose: () => void 62 }) { 63 + const {track} = useAnalytics() 64 const pal = usePalette('default') 65 const store = useStores() 66 const textInput = useRef<PasteInputRef>(null) ··· 254 autocompleteView.knownHandles, 255 setProcessingState, 256 ) 257 + track('Create Post', { 258 + imageCount: selectedPhotos.length, 259 + }) 260 } catch (e: any) { 261 setError(cleanError(e.message)) 262 setIsProcessing(false)
+3
src/view/com/login/CreateAccount.tsx
··· 12 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 13 import {ComAtprotoAccountCreate} from '@atproto/api' 14 import * as EmailValidator from 'email-validator' 15 import {LogoTextHero} from './Logo' 16 import {Picker} from '../util/Picker' 17 import {TextLink} from '../util/Link' ··· 28 import {usePalette} from '../../lib/hooks/usePalette' 29 30 export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { 31 const pal = usePalette('default') 32 const store = useStores() 33 const [isProcessing, setIsProcessing] = useState<boolean>(false) ··· 104 password, 105 inviteCode, 106 }) 107 } catch (e: any) { 108 let errMsg = e.toString() 109 if (e instanceof ComAtprotoAccountCreate.InvalidInviteCodeError) {
··· 12 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 13 import {ComAtprotoAccountCreate} from '@atproto/api' 14 import * as EmailValidator from 'email-validator' 15 + import {useAnalytics} from '@segment/analytics-react-native' 16 import {LogoTextHero} from './Logo' 17 import {Picker} from '../util/Picker' 18 import {TextLink} from '../util/Link' ··· 29 import {usePalette} from '../../lib/hooks/usePalette' 30 31 export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { 32 + const {track} = useAnalytics() 33 const pal = usePalette('default') 34 const store = useStores() 35 const [isProcessing, setIsProcessing] = useState<boolean>(false) ··· 106 password, 107 inviteCode, 108 }) 109 + track('Create Account') 110 } catch (e: any) { 111 let errMsg = e.toString() 112 if (e instanceof ComAtprotoAccountCreate.InvalidInviteCodeError) {
+5
src/view/com/login/Signin.tsx
··· 11 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 12 import * as EmailValidator from 'email-validator' 13 import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' 14 import {LogoTextHero} from './Logo' 15 import {Text} from '../util/text/Text' 16 import {UserAvatar} from '../util/UserAvatar' ··· 149 onSelectAccount: (account?: AccountData) => void 150 onPressBack: () => void 151 }) => { 152 const pal = usePalette('default') 153 const [isProcessing, setIsProcessing] = React.useState(false) 154 ··· 156 if (account.accessJwt && account.refreshJwt) { 157 setIsProcessing(true) 158 if (await store.session.resumeSession(account)) { 159 setIsProcessing(false) 160 return 161 } ··· 255 onPressBack: () => void 256 onPressForgotPassword: () => void 257 }) => { 258 const pal = usePalette('default') 259 const [isProcessing, setIsProcessing] = useState<boolean>(false) 260 const [handle, setHandle] = useState<string>(initialHandle) ··· 295 handle: fullHandle, 296 password, 297 }) 298 } catch (e: any) { 299 const errMsg = e.toString() 300 store.log.warn('Failed to login', e)
··· 11 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 12 import * as EmailValidator from 'email-validator' 13 import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' 14 + import {useAnalytics} from '@segment/analytics-react-native' 15 import {LogoTextHero} from './Logo' 16 import {Text} from '../util/text/Text' 17 import {UserAvatar} from '../util/UserAvatar' ··· 150 onSelectAccount: (account?: AccountData) => void 151 onPressBack: () => void 152 }) => { 153 + const {track} = useAnalytics() 154 const pal = usePalette('default') 155 const [isProcessing, setIsProcessing] = React.useState(false) 156 ··· 158 if (account.accessJwt && account.refreshJwt) { 159 setIsProcessing(true) 160 if (await store.session.resumeSession(account)) { 161 + track('Sign In', {resumedSession: true}) 162 setIsProcessing(false) 163 return 164 } ··· 258 onPressBack: () => void 259 onPressForgotPassword: () => void 260 }) => { 261 + const {track} = useAnalytics() 262 const pal = usePalette('default') 263 const [isProcessing, setIsProcessing] = useState<boolean>(false) 264 const [handle, setHandle] = useState<string>(initialHandle) ··· 299 handle: fullHandle, 300 password, 301 }) 302 + track('Sign In', {resumedSession: false}) 303 } catch (e: any) { 304 const errMsg = e.toString() 305 store.log.warn('Failed to login', e)
+125 -7
yarn.lock
··· 2124 schema-utils "^3.0.0" 2125 source-map "^0.7.3" 2126 2127 - "@react-native-async-storage/async-storage@^1.17.6": 2128 version "1.17.11" 2129 resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz#7ec329c1b9f610e344602e806b04d7c928a2341d" 2130 integrity sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw== ··· 2409 version "1.2.0" 2410 resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" 2411 integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== 2412 2413 "@sideway/address@^4.1.3": 2414 version "4.1.4" ··· 3434 resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" 3435 integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== 3436 3437 ansi-regex@^4.1.0: 3438 version "4.1.1" 3439 resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" 3440 integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== 3441 3442 - ansi-regex@^5.0.0, ansi-regex@^5.0.1: 3443 - version "5.0.1" 3444 - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 3445 - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 3446 - 3447 ansi-regex@^6.0.1: 3448 version "6.0.1" 3449 resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" ··· 3576 define-properties "^1.1.4" 3577 es-abstract "^1.20.4" 3578 es-shim-unscopables "^1.0.0" 3579 3580 array.prototype.reduce@^1.0.5: 3581 version "1.0.5" ··· 5468 resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" 5469 integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== 5470 5471 es-module-lexer@^0.9.0: 5472 version "0.9.3" 5473 resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" ··· 7033 css-in-js-utils "^3.1.0" 7034 fast-loops "^1.1.3" 7035 7036 - internal-slot@^1.0.3: 7037 version "1.0.4" 7038 resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3" 7039 integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== ··· 7078 dependencies: 7079 kind-of "^6.0.0" 7080 7081 is-arrayish@^0.2.1: 7082 version "0.2.1" 7083 resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" ··· 7220 resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" 7221 integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== 7222 7223 is-module@^1.0.0: 7224 version "1.0.0" 7225 resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" ··· 7299 resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" 7300 integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== 7301 7302 is-shared-array-buffer@^1.0.2: 7303 version "1.0.2" 7304 resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" ··· 7369 resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 7370 integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== 7371 7372 isexe@^2.0.0: 7373 version "2.0.0" 7374 resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" ··· 7432 dependencies: 7433 html-escaper "^2.0.0" 7434 istanbul-lib-report "^3.0.0" 7435 7436 jake@^10.8.5: 7437 version "10.8.5" ··· 8329 "@sideway/formula" "^3.0.0" 8330 "@sideway/pinpoint" "^2.0.0" 8331 8332 js-sdsl@^4.1.4: 8333 version "4.2.0" 8334 resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" ··· 10836 resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 10837 integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 10838 10839 promise@^7.1.1: 10840 version "7.3.1" 10841 resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" ··· 11210 integrity sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ== 11211 dependencies: 11212 whatwg-url-without-unicode "8.0.0-3" 11213 11214 react-native-version-number@^0.3.6: 11215 version "0.3.6" ··· 12009 resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 12010 integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 12011 12012 shell-quote@^1.6.1, shell-quote@^1.7.3: 12013 version "1.7.4" 12014 resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" ··· 12278 version "1.5.0" 12279 resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 12280 integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== 12281 12282 string-hash-64@^1.0.3: 12283 version "1.0.3"
··· 2124 schema-utils "^3.0.0" 2125 source-map "^0.7.3" 2126 2127 + "@react-native-async-storage/async-storage@^1.15.15", "@react-native-async-storage/async-storage@^1.15.17", "@react-native-async-storage/async-storage@^1.17.6": 2128 version "1.17.11" 2129 resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.17.11.tgz#7ec329c1b9f610e344602e806b04d7c928a2341d" 2130 integrity sha512-bzs45n5HNcDq6mxXnSsOHysZWn1SbbebNxldBXCQs8dSvF8Aor9KCdpm+TpnnGweK3R6diqsT8lFhX77VX0NFw== ··· 2409 version "1.2.0" 2410 resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" 2411 integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== 2412 + 2413 + "@segment/analytics-react-native@^2.10.1": 2414 + version "2.10.1" 2415 + resolved "https://registry.yarnpkg.com/@segment/analytics-react-native/-/analytics-react-native-2.10.1.tgz#cfc6c2186eaffc31a73b2ea1f229581dbad1f928" 2416 + integrity sha512-9CzqVijoQK86K/piItYfg88sFSHOg9G2RmZ0uKQyrplHo0Cm3ngzzyhf7Ry/A7XNT6ebIIgMrh8UGIRR7YwY3g== 2417 + dependencies: 2418 + "@react-native-async-storage/async-storage" "^1.15.17" 2419 + "@segment/sovran-react-native" "^0.4.5" 2420 + deepmerge "^4.2.2" 2421 + js-base64 "^3.7.2" 2422 + promise.allsettled "^1.0.5" 2423 + react-native-uuid "^2.0.1" 2424 + 2425 + "@segment/sovran-react-native@^0.4.5": 2426 + version "0.4.5" 2427 + resolved "https://registry.yarnpkg.com/@segment/sovran-react-native/-/sovran-react-native-0.4.5.tgz#2ae057790623cfbd84eb15e4a3bb9835d108f815" 2428 + integrity sha512-/dvud4hkszRNgTHdb7p822U+NXTuPxifqQzhcrfdjmFoXMafnzOUAi1KxeGV6Qdb73VAIxcnr/8hkTqdjZ3YLw== 2429 + dependencies: 2430 + "@react-native-async-storage/async-storage" "^1.15.15" 2431 + ansi-regex "5.0.1" 2432 + deepmerge "^4.2.2" 2433 + shell-quote "1.7.3" 2434 2435 "@sideway/address@^4.1.3": 2436 version "4.1.4" ··· 3456 resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" 3457 integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== 3458 3459 + ansi-regex@5.0.1, ansi-regex@^5.0.0, ansi-regex@^5.0.1: 3460 + version "5.0.1" 3461 + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 3462 + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 3463 + 3464 ansi-regex@^4.1.0: 3465 version "4.1.1" 3466 resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" 3467 integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== 3468 3469 ansi-regex@^6.0.1: 3470 version "6.0.1" 3471 resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" ··· 3598 define-properties "^1.1.4" 3599 es-abstract "^1.20.4" 3600 es-shim-unscopables "^1.0.0" 3601 + 3602 + array.prototype.map@^1.0.5: 3603 + version "1.0.5" 3604 + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.5.tgz#6e43c2fee6c0fb5e4806da2dc92eb00970809e55" 3605 + integrity sha512-gfaKntvwqYIuC7mLLyv2wzZIJqrRhn5PZ9EfFejSx6a78sV7iDsGpG9P+3oUPtm1Rerqm6nrKS4FYuTIvWfo3g== 3606 + dependencies: 3607 + call-bind "^1.0.2" 3608 + define-properties "^1.1.4" 3609 + es-abstract "^1.20.4" 3610 + es-array-method-boxes-properly "^1.0.0" 3611 + is-string "^1.0.7" 3612 3613 array.prototype.reduce@^1.0.5: 3614 version "1.0.5" ··· 5501 resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" 5502 integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== 5503 5504 + es-get-iterator@^1.0.2: 5505 + version "1.1.3" 5506 + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" 5507 + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== 5508 + dependencies: 5509 + call-bind "^1.0.2" 5510 + get-intrinsic "^1.1.3" 5511 + has-symbols "^1.0.3" 5512 + is-arguments "^1.1.1" 5513 + is-map "^2.0.2" 5514 + is-set "^2.0.2" 5515 + is-string "^1.0.7" 5516 + isarray "^2.0.5" 5517 + stop-iteration-iterator "^1.0.0" 5518 + 5519 es-module-lexer@^0.9.0: 5520 version "0.9.3" 5521 resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" ··· 7081 css-in-js-utils "^3.1.0" 7082 fast-loops "^1.1.3" 7083 7084 + internal-slot@^1.0.3, internal-slot@^1.0.4: 7085 version "1.0.4" 7086 resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3" 7087 integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== ··· 7126 dependencies: 7127 kind-of "^6.0.0" 7128 7129 + is-arguments@^1.1.1: 7130 + version "1.1.1" 7131 + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" 7132 + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== 7133 + dependencies: 7134 + call-bind "^1.0.2" 7135 + has-tostringtag "^1.0.0" 7136 + 7137 is-arrayish@^0.2.1: 7138 version "0.2.1" 7139 resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" ··· 7276 resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" 7277 integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== 7278 7279 + is-map@^2.0.2: 7280 + version "2.0.2" 7281 + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" 7282 + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== 7283 + 7284 is-module@^1.0.0: 7285 version "1.0.0" 7286 resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" ··· 7360 resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" 7361 integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== 7362 7363 + is-set@^2.0.2: 7364 + version "2.0.2" 7365 + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" 7366 + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== 7367 + 7368 is-shared-array-buffer@^1.0.2: 7369 version "1.0.2" 7370 resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" ··· 7435 resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 7436 integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== 7437 7438 + isarray@^2.0.5: 7439 + version "2.0.5" 7440 + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" 7441 + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== 7442 + 7443 isexe@^2.0.0: 7444 version "2.0.0" 7445 resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" ··· 7503 dependencies: 7504 html-escaper "^2.0.0" 7505 istanbul-lib-report "^3.0.0" 7506 + 7507 + iterate-iterator@^1.0.1: 7508 + version "1.0.2" 7509 + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" 7510 + integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== 7511 + 7512 + iterate-value@^1.0.2: 7513 + version "1.0.2" 7514 + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" 7515 + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== 7516 + dependencies: 7517 + es-get-iterator "^1.0.2" 7518 + iterate-iterator "^1.0.1" 7519 7520 jake@^10.8.5: 7521 version "10.8.5" ··· 8413 "@sideway/formula" "^3.0.0" 8414 "@sideway/pinpoint" "^2.0.0" 8415 8416 + js-base64@^3.7.2: 8417 + version "3.7.4" 8418 + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.4.tgz#af95b20f23efc8034afd2d1cc5b9d0adf7419037" 8419 + integrity sha512-wpM/wi20Tl+3ifTyi0RdDckS4YTD4Lf953mBRrpG8547T7hInHNPEj8+ck4gB8VDcGyeAWFK++Wb/fU1BeavKQ== 8420 + 8421 js-sdsl@^4.1.4: 8422 version "4.2.0" 8423 resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" ··· 10925 resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 10926 integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 10927 10928 + promise.allsettled@^1.0.5: 10929 + version "1.0.6" 10930 + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.6.tgz#8dc8ba8edf429feb60f8e81335b920e109c94b6e" 10931 + integrity sha512-22wJUOD3zswWFqgwjNHa1965LvqTX87WPu/lreY2KSd7SVcERfuZ4GfUaOnJNnvtoIv2yXT/W00YIGMetXtFXg== 10932 + dependencies: 10933 + array.prototype.map "^1.0.5" 10934 + call-bind "^1.0.2" 10935 + define-properties "^1.1.4" 10936 + es-abstract "^1.20.4" 10937 + get-intrinsic "^1.1.3" 10938 + iterate-value "^1.0.2" 10939 + 10940 promise@^7.1.1: 10941 version "7.3.1" 10942 resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" ··· 11311 integrity sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ== 11312 dependencies: 11313 whatwg-url-without-unicode "8.0.0-3" 11314 + 11315 + react-native-uuid@^2.0.1: 11316 + version "2.0.1" 11317 + resolved "https://registry.yarnpkg.com/react-native-uuid/-/react-native-uuid-2.0.1.tgz#ed4e2dfb1683eddb66967eb5dca140dfe1abddb9" 11318 + integrity sha512-cptnoIbL53GTCrWlb/+jrDC6tvb7ypIyzbXNJcpR3Vab0mkeaaVd5qnB3f0whXYzS+SMoSQLcUUB0gEWqkPC0g== 11319 11320 react-native-version-number@^0.3.6: 11321 version "0.3.6" ··· 12115 resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 12116 integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 12117 12118 + shell-quote@1.7.3: 12119 + version "1.7.3" 12120 + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" 12121 + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== 12122 + 12123 shell-quote@^1.6.1, shell-quote@^1.7.3: 12124 version "1.7.4" 12125 resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" ··· 12389 version "1.5.0" 12390 resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 12391 integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== 12392 + 12393 + stop-iteration-iterator@^1.0.0: 12394 + version "1.0.0" 12395 + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" 12396 + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== 12397 + dependencies: 12398 + internal-slot "^1.0.4" 12399 12400 string-hash-64@^1.0.3: 12401 version "1.0.3"