From 134ed6b20256c77aad7165b694244b6ca0f291ee Mon Sep 17 00:00:00 2001 From: ItsFlash10 Date: Fri, 17 Jan 2025 03:55:37 +0530 Subject: [PATCH] mobile app init with onboarding --- apps/mobile/.eslintignore | 8 + apps/mobile/.eslintrc.js | 59 + apps/mobile/.gitignore | 92 + apps/mobile/.prettierignore | 9 + apps/mobile/.prettierrc | 11 + apps/mobile/README.md | 77 + apps/mobile/app.config.ts | 22 + apps/mobile/app.json | 69 + apps/mobile/app/app.tsx | 114 + apps/mobile/app/components/AutoImage.tsx | 89 + apps/mobile/app/components/Button.tsx | 248 + apps/mobile/app/components/Card.tsx | 314 + apps/mobile/app/components/EmptyState.tsx | 248 + apps/mobile/app/components/Header.tsx | 327 + apps/mobile/app/components/Icon.tsx | 109 + apps/mobile/app/components/ListItem.tsx | 235 + apps/mobile/app/components/ListView.tsx | 43 + apps/mobile/app/components/Screen.tsx | 307 + apps/mobile/app/components/Text.test.tsx | 15 + apps/mobile/app/components/Text.tsx | 116 + apps/mobile/app/components/TextField.tsx | 290 + .../mobile/app/components/Toggle/Checkbox.tsx | 123 + apps/mobile/app/components/Toggle/Radio.tsx | 106 + apps/mobile/app/components/Toggle/Switch.tsx | 273 + apps/mobile/app/components/Toggle/Toggle.tsx | 285 + apps/mobile/app/components/Toggle/index.ts | 3 + apps/mobile/app/components/index.ts | 12 + apps/mobile/app/config/config.base.ts | 26 + apps/mobile/app/config/config.dev.ts | 10 + apps/mobile/app/config/config.prod.ts | 10 + apps/mobile/app/config/index.ts | 28 + apps/mobile/app/constants/common.constants.ts | 9 + apps/mobile/app/constants/index.ts | 1 + apps/mobile/app/devtools/ReactotronClient.ts | 9 + .../app/devtools/ReactotronClient.web.ts | 12 + apps/mobile/app/devtools/ReactotronConfig.ts | 139 + apps/mobile/app/i18n/ar.ts | 30 + apps/mobile/app/i18n/en.ts | 29 + apps/mobile/app/i18n/es.ts | 31 + apps/mobile/app/i18n/fr.ts | 31 + apps/mobile/app/i18n/hi.ts | 30 + apps/mobile/app/i18n/i18n.ts | 87 + apps/mobile/app/i18n/index.ts | 4 + apps/mobile/app/i18n/ja.ts | 31 + apps/mobile/app/i18n/ko.ts | 30 + apps/mobile/app/i18n/translate.ts | 33 + apps/mobile/app/navigators/AppNavigator.tsx | 91 + apps/mobile/app/navigators/index.ts | 3 + .../app/navigators/navigationUtilities.ts | 208 + .../app/screens/ErrorScreen/ErrorBoundary.tsx | 76 + .../app/screens/ErrorScreen/ErrorDetails.tsx | 96 + apps/mobile/app/screens/OnboardingScreen.tsx | 426 + apps/mobile/app/screens/WelcomeScreen.tsx | 84 + apps/mobile/app/screens/index.ts | 4 + apps/mobile/app/services/api/api.ts | 45 + apps/mobile/app/services/api/api.types.ts | 50 + .../app/services/api/apiProblem.test.ts | 73 + apps/mobile/app/services/api/apiProblem.ts | 74 + apps/mobile/app/services/api/index.ts | 2 + apps/mobile/app/theme/colors.ts | 85 + apps/mobile/app/theme/colorsDark.ts | 50 + apps/mobile/app/theme/index.ts | 81 + apps/mobile/app/theme/spacing.ts | 14 + apps/mobile/app/theme/spacingDark.ts | 14 + apps/mobile/app/theme/styles.ts | 19 + apps/mobile/app/theme/timing.ts | 6 + apps/mobile/app/theme/typography.ts | 71 + apps/mobile/app/utils/crashReporting.ts | 62 + apps/mobile/app/utils/delay.ts | 6 + apps/mobile/app/utils/formatDate.ts | 49 + .../mobile/app/utils/gestureHandler.native.ts | 3 + apps/mobile/app/utils/gestureHandler.ts | 5 + apps/mobile/app/utils/ignoreWarnings.ts | 11 + apps/mobile/app/utils/index.ts | 1 + apps/mobile/app/utils/openLinkInBrowser.ts | 8 + apps/mobile/app/utils/storage/index.ts | 1 + apps/mobile/app/utils/storage/storage.test.ts | 61 + apps/mobile/app/utils/storage/storage.ts | 82 + apps/mobile/app/utils/useAppTheme.ts | 122 + apps/mobile/app/utils/useHeader.tsx | 38 + apps/mobile/app/utils/useIsMounted.ts | 19 + .../app/utils/useSafeAreaInsetsStyle.ts | 46 + apps/mobile/assets/icons/back.png | Bin 0 -> 411 bytes apps/mobile/assets/icons/back@2x.png | Bin 0 -> 636 bytes apps/mobile/assets/icons/back@3x.png | Bin 0 -> 782 bytes apps/mobile/assets/icons/bell.png | Bin 0 -> 720 bytes apps/mobile/assets/icons/bell@2x.png | Bin 0 -> 1571 bytes apps/mobile/assets/icons/bell@3x.png | Bin 0 -> 2282 bytes apps/mobile/assets/icons/caretLeft.png | Bin 0 -> 393 bytes apps/mobile/assets/icons/caretLeft@2x.png | Bin 0 -> 614 bytes apps/mobile/assets/icons/caretLeft@3x.png | Bin 0 -> 704 bytes apps/mobile/assets/icons/caretRight.png | Bin 0 -> 367 bytes apps/mobile/assets/icons/caretRight@2x.png | Bin 0 -> 602 bytes apps/mobile/assets/icons/caretRight@3x.png | Bin 0 -> 723 bytes apps/mobile/assets/icons/check.png | Bin 0 -> 404 bytes apps/mobile/assets/icons/check@2x.png | Bin 0 -> 623 bytes apps/mobile/assets/icons/check@3x.png | Bin 0 -> 776 bytes apps/mobile/assets/icons/hidden.png | Bin 0 -> 1060 bytes apps/mobile/assets/icons/hidden@2x.png | Bin 0 -> 2253 bytes apps/mobile/assets/icons/hidden@3x.png | Bin 0 -> 3385 bytes apps/mobile/assets/icons/ladybug.png | Bin 0 -> 1206 bytes apps/mobile/assets/icons/ladybug@2x.png | Bin 0 -> 3152 bytes apps/mobile/assets/icons/ladybug@3x.png | Bin 0 -> 5247 bytes apps/mobile/assets/icons/lock.png | Bin 0 -> 618 bytes apps/mobile/assets/icons/lock@2x.png | Bin 0 -> 1150 bytes apps/mobile/assets/icons/lock@3x.png | Bin 0 -> 1692 bytes apps/mobile/assets/icons/menu.png | Bin 0 -> 227 bytes apps/mobile/assets/icons/menu@2x.png | Bin 0 -> 342 bytes apps/mobile/assets/icons/menu@3x.png | Bin 0 -> 484 bytes apps/mobile/assets/icons/more.png | Bin 0 -> 243 bytes apps/mobile/assets/icons/more@2x.png | Bin 0 -> 394 bytes apps/mobile/assets/icons/more@3x.png | Bin 0 -> 569 bytes apps/mobile/assets/icons/settings.png | Bin 0 -> 1252 bytes apps/mobile/assets/icons/settings@2x.png | Bin 0 -> 2892 bytes apps/mobile/assets/icons/settings@3x.png | Bin 0 -> 4469 bytes apps/mobile/assets/icons/view.png | Bin 0 -> 796 bytes apps/mobile/assets/icons/view@2x.png | Bin 0 -> 1890 bytes apps/mobile/assets/icons/view@3x.png | Bin 0 -> 2814 bytes apps/mobile/assets/icons/x.png | Bin 0 -> 472 bytes apps/mobile/assets/icons/x@2x.png | Bin 0 -> 814 bytes apps/mobile/assets/icons/x@3x.png | Bin 0 -> 1008 bytes apps/mobile/assets/images/app-icon-all.png | Bin 0 -> 256851 bytes .../app-icon-android-adaptive-background.png | Bin 0 -> 5354 bytes .../app-icon-android-adaptive-foreground.png | Bin 0 -> 313644 bytes .../assets/images/app-icon-android-legacy.png | Bin 0 -> 256858 bytes apps/mobile/assets/images/app-icon-ios.png | Bin 0 -> 256851 bytes .../assets/images/app-icon-web-favicon.png | Bin 0 -> 1739 bytes apps/mobile/assets/images/email-hero.png | Bin 0 -> 272096 bytes apps/mobile/assets/images/header-light.png | Bin 0 -> 182166 bytes apps/mobile/assets/images/landing.png | Bin 0 -> 928778 bytes apps/mobile/assets/images/logo.png | Bin 0 -> 299591 bytes apps/mobile/assets/images/logo@2x.png | Bin 0 -> 299591 bytes apps/mobile/assets/images/logo@3x.png | Bin 0 -> 299591 bytes apps/mobile/assets/images/name-hero.png | Bin 0 -> 257480 bytes apps/mobile/assets/images/otp-hero.png | Bin 0 -> 278959 bytes apps/mobile/assets/images/sad-face.png | Bin 0 -> 11830 bytes apps/mobile/assets/images/sad-face@2x.png | Bin 0 -> 36321 bytes apps/mobile/assets/images/sad-face@3x.png | Bin 0 -> 75212 bytes apps/mobile/assets/images/splash-logo-all.png | Bin 0 -> 116287 bytes .../images/splash-logo-android-universal.png | Bin 0 -> 186685 bytes .../assets/images/splash-logo-ios-mobile.png | Bin 0 -> 152253 bytes .../assets/images/splash-logo-ios-tablet.png | Bin 0 -> 93832 bytes apps/mobile/assets/images/splash-logo-web.png | Bin 0 -> 48262 bytes apps/mobile/assets/images/welcome-face.png | Bin 0 -> 12129 bytes apps/mobile/assets/images/welcome-face@2x.png | Bin 0 -> 37275 bytes apps/mobile/assets/images/welcome-face@3x.png | Bin 0 -> 77799 bytes apps/mobile/babel.config.js | 7 + apps/mobile/eas.json | 40 + .../app-icon/android-adaptive-background.png | Bin 0 -> 15860 bytes .../app-icon/android-adaptive-foreground.png | Bin 0 -> 299591 bytes .../templates/app-icon/android-legacy.png | Bin 0 -> 233407 bytes .../templates/app-icon/ios-universal.png | Bin 0 -> 233414 bytes .../ignite/templates/component/NAME.tsx.ejs | 45 + .../templates/navigator/NAMENavigator.tsx.ejs | 24 + .../templates/screen/NAMEScreen.tsx.ejs | 38 + .../ignite/templates/splash-screen/logo.png | Bin 0 -> 299591 bytes apps/mobile/index.tsx | 10 + apps/mobile/jest.config.js | 5 + apps/mobile/metro.config.js | 41 + apps/mobile/package.json | 114 + apps/mobile/plugins/withSplashScreen.ts | 69 + apps/mobile/test/i18n.test.ts | 67 + apps/mobile/test/mockFile.ts | 6 + apps/mobile/test/setup.ts | 57 + apps/mobile/test/test-tsconfig.json | 21 + apps/mobile/tsconfig.json | 32 + apps/mobile/types/lib.es5.d.ts | 25 + apps/mobile/yarn.lock | 9988 +++++++++++++++++ 168 files changed, 16859 insertions(+) create mode 100644 apps/mobile/.eslintignore create mode 100644 apps/mobile/.eslintrc.js create mode 100644 apps/mobile/.gitignore create mode 100644 apps/mobile/.prettierignore create mode 100644 apps/mobile/.prettierrc create mode 100644 apps/mobile/README.md create mode 100644 apps/mobile/app.config.ts create mode 100644 apps/mobile/app.json create mode 100644 apps/mobile/app/app.tsx create mode 100644 apps/mobile/app/components/AutoImage.tsx create mode 100644 apps/mobile/app/components/Button.tsx create mode 100644 apps/mobile/app/components/Card.tsx create mode 100644 apps/mobile/app/components/EmptyState.tsx create mode 100644 apps/mobile/app/components/Header.tsx create mode 100644 apps/mobile/app/components/Icon.tsx create mode 100644 apps/mobile/app/components/ListItem.tsx create mode 100644 apps/mobile/app/components/ListView.tsx create mode 100644 apps/mobile/app/components/Screen.tsx create mode 100644 apps/mobile/app/components/Text.test.tsx create mode 100644 apps/mobile/app/components/Text.tsx create mode 100644 apps/mobile/app/components/TextField.tsx create mode 100644 apps/mobile/app/components/Toggle/Checkbox.tsx create mode 100644 apps/mobile/app/components/Toggle/Radio.tsx create mode 100644 apps/mobile/app/components/Toggle/Switch.tsx create mode 100644 apps/mobile/app/components/Toggle/Toggle.tsx create mode 100644 apps/mobile/app/components/Toggle/index.ts create mode 100644 apps/mobile/app/components/index.ts create mode 100644 apps/mobile/app/config/config.base.ts create mode 100644 apps/mobile/app/config/config.dev.ts create mode 100644 apps/mobile/app/config/config.prod.ts create mode 100644 apps/mobile/app/config/index.ts create mode 100644 apps/mobile/app/constants/common.constants.ts create mode 100644 apps/mobile/app/constants/index.ts create mode 100644 apps/mobile/app/devtools/ReactotronClient.ts create mode 100644 apps/mobile/app/devtools/ReactotronClient.web.ts create mode 100644 apps/mobile/app/devtools/ReactotronConfig.ts create mode 100644 apps/mobile/app/i18n/ar.ts create mode 100644 apps/mobile/app/i18n/en.ts create mode 100644 apps/mobile/app/i18n/es.ts create mode 100644 apps/mobile/app/i18n/fr.ts create mode 100644 apps/mobile/app/i18n/hi.ts create mode 100644 apps/mobile/app/i18n/i18n.ts create mode 100644 apps/mobile/app/i18n/index.ts create mode 100644 apps/mobile/app/i18n/ja.ts create mode 100644 apps/mobile/app/i18n/ko.ts create mode 100644 apps/mobile/app/i18n/translate.ts create mode 100644 apps/mobile/app/navigators/AppNavigator.tsx create mode 100644 apps/mobile/app/navigators/index.ts create mode 100644 apps/mobile/app/navigators/navigationUtilities.ts create mode 100644 apps/mobile/app/screens/ErrorScreen/ErrorBoundary.tsx create mode 100644 apps/mobile/app/screens/ErrorScreen/ErrorDetails.tsx create mode 100644 apps/mobile/app/screens/OnboardingScreen.tsx create mode 100644 apps/mobile/app/screens/WelcomeScreen.tsx create mode 100644 apps/mobile/app/screens/index.ts create mode 100644 apps/mobile/app/services/api/api.ts create mode 100644 apps/mobile/app/services/api/api.types.ts create mode 100644 apps/mobile/app/services/api/apiProblem.test.ts create mode 100644 apps/mobile/app/services/api/apiProblem.ts create mode 100644 apps/mobile/app/services/api/index.ts create mode 100644 apps/mobile/app/theme/colors.ts create mode 100644 apps/mobile/app/theme/colorsDark.ts create mode 100644 apps/mobile/app/theme/index.ts create mode 100644 apps/mobile/app/theme/spacing.ts create mode 100644 apps/mobile/app/theme/spacingDark.ts create mode 100644 apps/mobile/app/theme/styles.ts create mode 100644 apps/mobile/app/theme/timing.ts create mode 100644 apps/mobile/app/theme/typography.ts create mode 100644 apps/mobile/app/utils/crashReporting.ts create mode 100644 apps/mobile/app/utils/delay.ts create mode 100644 apps/mobile/app/utils/formatDate.ts create mode 100644 apps/mobile/app/utils/gestureHandler.native.ts create mode 100644 apps/mobile/app/utils/gestureHandler.ts create mode 100644 apps/mobile/app/utils/ignoreWarnings.ts create mode 100644 apps/mobile/app/utils/index.ts create mode 100644 apps/mobile/app/utils/openLinkInBrowser.ts create mode 100644 apps/mobile/app/utils/storage/index.ts create mode 100644 apps/mobile/app/utils/storage/storage.test.ts create mode 100644 apps/mobile/app/utils/storage/storage.ts create mode 100644 apps/mobile/app/utils/useAppTheme.ts create mode 100644 apps/mobile/app/utils/useHeader.tsx create mode 100644 apps/mobile/app/utils/useIsMounted.ts create mode 100644 apps/mobile/app/utils/useSafeAreaInsetsStyle.ts create mode 100644 apps/mobile/assets/icons/back.png create mode 100644 apps/mobile/assets/icons/back@2x.png create mode 100644 apps/mobile/assets/icons/back@3x.png create mode 100644 apps/mobile/assets/icons/bell.png create mode 100644 apps/mobile/assets/icons/bell@2x.png create mode 100644 apps/mobile/assets/icons/bell@3x.png create mode 100644 apps/mobile/assets/icons/caretLeft.png create mode 100644 apps/mobile/assets/icons/caretLeft@2x.png create mode 100644 apps/mobile/assets/icons/caretLeft@3x.png create mode 100644 apps/mobile/assets/icons/caretRight.png create mode 100644 apps/mobile/assets/icons/caretRight@2x.png create mode 100644 apps/mobile/assets/icons/caretRight@3x.png create mode 100644 apps/mobile/assets/icons/check.png create mode 100644 apps/mobile/assets/icons/check@2x.png create mode 100644 apps/mobile/assets/icons/check@3x.png create mode 100644 apps/mobile/assets/icons/hidden.png create mode 100644 apps/mobile/assets/icons/hidden@2x.png create mode 100644 apps/mobile/assets/icons/hidden@3x.png create mode 100644 apps/mobile/assets/icons/ladybug.png create mode 100644 apps/mobile/assets/icons/ladybug@2x.png create mode 100644 apps/mobile/assets/icons/ladybug@3x.png create mode 100644 apps/mobile/assets/icons/lock.png create mode 100644 apps/mobile/assets/icons/lock@2x.png create mode 100644 apps/mobile/assets/icons/lock@3x.png create mode 100644 apps/mobile/assets/icons/menu.png create mode 100644 apps/mobile/assets/icons/menu@2x.png create mode 100644 apps/mobile/assets/icons/menu@3x.png create mode 100644 apps/mobile/assets/icons/more.png create mode 100644 apps/mobile/assets/icons/more@2x.png create mode 100644 apps/mobile/assets/icons/more@3x.png create mode 100644 apps/mobile/assets/icons/settings.png create mode 100644 apps/mobile/assets/icons/settings@2x.png create mode 100644 apps/mobile/assets/icons/settings@3x.png create mode 100644 apps/mobile/assets/icons/view.png create mode 100644 apps/mobile/assets/icons/view@2x.png create mode 100644 apps/mobile/assets/icons/view@3x.png create mode 100644 apps/mobile/assets/icons/x.png create mode 100644 apps/mobile/assets/icons/x@2x.png create mode 100644 apps/mobile/assets/icons/x@3x.png create mode 100644 apps/mobile/assets/images/app-icon-all.png create mode 100644 apps/mobile/assets/images/app-icon-android-adaptive-background.png create mode 100644 apps/mobile/assets/images/app-icon-android-adaptive-foreground.png create mode 100644 apps/mobile/assets/images/app-icon-android-legacy.png create mode 100644 apps/mobile/assets/images/app-icon-ios.png create mode 100644 apps/mobile/assets/images/app-icon-web-favicon.png create mode 100644 apps/mobile/assets/images/email-hero.png create mode 100644 apps/mobile/assets/images/header-light.png create mode 100644 apps/mobile/assets/images/landing.png create mode 100644 apps/mobile/assets/images/logo.png create mode 100644 apps/mobile/assets/images/logo@2x.png create mode 100644 apps/mobile/assets/images/logo@3x.png create mode 100644 apps/mobile/assets/images/name-hero.png create mode 100644 apps/mobile/assets/images/otp-hero.png create mode 100644 apps/mobile/assets/images/sad-face.png create mode 100644 apps/mobile/assets/images/sad-face@2x.png create mode 100644 apps/mobile/assets/images/sad-face@3x.png create mode 100644 apps/mobile/assets/images/splash-logo-all.png create mode 100644 apps/mobile/assets/images/splash-logo-android-universal.png create mode 100644 apps/mobile/assets/images/splash-logo-ios-mobile.png create mode 100644 apps/mobile/assets/images/splash-logo-ios-tablet.png create mode 100644 apps/mobile/assets/images/splash-logo-web.png create mode 100644 apps/mobile/assets/images/welcome-face.png create mode 100644 apps/mobile/assets/images/welcome-face@2x.png create mode 100644 apps/mobile/assets/images/welcome-face@3x.png create mode 100644 apps/mobile/babel.config.js create mode 100644 apps/mobile/eas.json create mode 100644 apps/mobile/ignite/templates/app-icon/android-adaptive-background.png create mode 100644 apps/mobile/ignite/templates/app-icon/android-adaptive-foreground.png create mode 100644 apps/mobile/ignite/templates/app-icon/android-legacy.png create mode 100644 apps/mobile/ignite/templates/app-icon/ios-universal.png create mode 100644 apps/mobile/ignite/templates/component/NAME.tsx.ejs create mode 100644 apps/mobile/ignite/templates/navigator/NAMENavigator.tsx.ejs create mode 100644 apps/mobile/ignite/templates/screen/NAMEScreen.tsx.ejs create mode 100644 apps/mobile/ignite/templates/splash-screen/logo.png create mode 100644 apps/mobile/index.tsx create mode 100644 apps/mobile/jest.config.js create mode 100644 apps/mobile/metro.config.js create mode 100644 apps/mobile/package.json create mode 100644 apps/mobile/plugins/withSplashScreen.ts create mode 100644 apps/mobile/test/i18n.test.ts create mode 100644 apps/mobile/test/mockFile.ts create mode 100644 apps/mobile/test/setup.ts create mode 100644 apps/mobile/test/test-tsconfig.json create mode 100644 apps/mobile/tsconfig.json create mode 100644 apps/mobile/types/lib.es5.d.ts create mode 100644 apps/mobile/yarn.lock diff --git a/apps/mobile/.eslintignore b/apps/mobile/.eslintignore new file mode 100644 index 0000000..408b6c8 --- /dev/null +++ b/apps/mobile/.eslintignore @@ -0,0 +1,8 @@ +node_modules +ios +android +.expo +.vscode +ignite/ignite.json +package.json +.eslintignore diff --git a/apps/mobile/.eslintrc.js b/apps/mobile/.eslintrc.js new file mode 100644 index 0000000..fc40f93 --- /dev/null +++ b/apps/mobile/.eslintrc.js @@ -0,0 +1,59 @@ +// https://docs.expo.dev/guides/using-eslint/ +module.exports = { + extends: [ + "standard", + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended", + "plugin:react-native/all", + // `expo` must come after `standard` or its globals configuration will be overridden + "expo", + // `jsx-runtime` must come after `expo` or it will be overridden + "plugin:react/jsx-runtime", + "prettier", + ], + plugins: ["reactotron", "prettier"], + rules: { + "prettier/prettier": "error", + // typescript-eslint + "@typescript-eslint/array-type": 0, + "@typescript-eslint/ban-ts-comment": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + }, + ], + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/no-require-imports": 0, + "@typescript-eslint/no-empty-object-type": 0, + // eslint + "no-use-before-define": 0, + "no-restricted-imports": [ + "error", + { + paths: [ + // Prefer named exports from 'react' instead of importing `React` + { + name: "react", + importNames: ["default"], + message: "Import named exports from 'react' instead.", + }, + ], + }, + ], + // react + "react/prop-types": 0, + // react-native + "react-native/no-raw-text": 0, + // reactotron + "reactotron/no-tron-in-production": "error", + // eslint-config-standard overrides + "comma-dangle": 0, + "no-global-assign": 0, + "quotes": 0, + "space-before-function-paren": 0, + "camelcase": 0, + }, +} diff --git a/apps/mobile/.gitignore b/apps/mobile/.gitignore new file mode 100644 index 0000000..3a54480 --- /dev/null +++ b/apps/mobile/.gitignore @@ -0,0 +1,92 @@ +# OSX +# +.DS_Store + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +ios/.xcode.env.local + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml +*.hprof +.cxx/ + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +*.keystore +!debug.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +**/fastlane/report.xml +**/fastlane/Preview.html +**/fastlane/screenshots +**/fastlane/test_output + +# Bundle artifact +*.jsbundle + +# Ignite-specific items below +# You can safely replace everything above this comment with whatever is +# in the default .gitignore generated by React-Native CLI + +# VS Code +.vscode + +# Expo +.expo/* +bin/Exponent.app +/android +/ios +expo-env.d.ts + +## Secrets +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ + +# Configurations +!env.js + +/coverage + +# Yarn +.yarn/* diff --git a/apps/mobile/.prettierignore b/apps/mobile/.prettierignore new file mode 100644 index 0000000..9acad61 --- /dev/null +++ b/apps/mobile/.prettierignore @@ -0,0 +1,9 @@ +node_modules +ios +android +.expo +.vscode +ignite/ignite.json +package.json +.eslintignore +app/app.tsx diff --git a/apps/mobile/.prettierrc b/apps/mobile/.prettierrc new file mode 100644 index 0000000..0ec1123 --- /dev/null +++ b/apps/mobile/.prettierrc @@ -0,0 +1,11 @@ +{ + "printWidth": 100, + "semi": false, + "singleQuote": false, + "trailingComma": "all", + "quoteProps": "consistent", + "plugins": ["@trivago/prettier-plugin-sort-imports"], + "importOrder": ["^(react|react-native)(/(.*))?$", "", "^@/(.*)$", "^[./]"], + "importOrderSeparation": true, + "importOrderSortSpecifiers": true +} diff --git a/apps/mobile/README.md b/apps/mobile/README.md new file mode 100644 index 0000000..ddd8e77 --- /dev/null +++ b/apps/mobile/README.md @@ -0,0 +1,77 @@ +# Welcome to your new ignited app! + +> The latest and greatest boilerplate for Infinite Red opinions + +This is the boilerplate that [Infinite Red](https://infinite.red) uses as a way to test bleeding-edge changes to our React Native stack. + +- [Quick start documentation](https://github.com/infinitered/ignite/blob/master/docs/boilerplate/Boilerplate.md) +- [Full documentation](https://github.com/infinitered/ignite/blob/master/docs/README.md) + +## Getting Started + +```bash +yarn +yarn start +``` + +To make things work on your local simulator, or on your phone, you need first to [run `eas build`](https://github.com/infinitered/ignite/blob/master/docs/expo/EAS.md). We have many shortcuts on `package.json` to make it easier: + +```bash +yarn build:ios:sim # build for ios simulator +yarn build:ios:dev # build for ios device +yarn build:ios:prod # build for ios device +``` + +### `./assets` directory + +This directory is designed to organize and store various assets, making it easy for you to manage and use them in your application. The assets are further categorized into subdirectories, including `icons` and `images`: + +```tree +assets +├── icons +└── images +``` + +**icons** +This is where your icon assets will live. These icons can be used for buttons, navigation elements, or any other UI components. The recommended format for icons is PNG, but other formats can be used as well. + +Ignite comes with a built-in `Icon` component. You can find detailed usage instructions in the [docs](https://github.com/infinitered/ignite/blob/master/docs/boilerplate/app/components/Icon.md). + +**images** +This is where your images will live, such as background images, logos, or any other graphics. You can use various formats such as PNG, JPEG, or GIF for your images. + +Another valuable built-in component within Ignite is the `AutoImage` component. You can find detailed usage instructions in the [docs](https://github.com/infinitered/ignite/blob/master/docs/Components-AutoImage.md). + +How to use your `icon` or `image` assets: + +```typescript +import { Image } from 'react-native'; + +const MyComponent = () => { + return ( + + ); +}; +``` + +## Running Maestro end-to-end tests + +Follow our [Maestro Setup](https://ignitecookbook.com/docs/recipes/MaestroSetup) recipe. + +## Next Steps + +### Ignite Cookbook + +[Ignite Cookbook](https://ignitecookbook.com/) is an easy way for developers to browse and share code snippets (or “recipes”) that actually work. + +### Upgrade Ignite boilerplate + +Read our [Upgrade Guide](https://ignitecookbook.com/docs/recipes/UpdatingIgnite) to learn how to upgrade your Ignite project. + +## Community + +⭐️ Help us out by [starring on GitHub](https://github.com/infinitered/ignite), filing bug reports in [issues](https://github.com/infinitered/ignite/issues) or [ask questions](https://github.com/infinitered/ignite/discussions). + +💬 Join us on [Slack](https://join.slack.com/t/infiniteredcommunity/shared_invite/zt-1f137np4h-zPTq_CbaRFUOR_glUFs2UA) to discuss. + +📰 Make our Editor-in-chief happy by [reading the React Native Newsletter](https://reactnativenewsletter.com/). diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts new file mode 100644 index 0000000..c4f57fd --- /dev/null +++ b/apps/mobile/app.config.ts @@ -0,0 +1,22 @@ +import { ConfigContext, ExpoConfig } from "@expo/config" + +/** + * Use ts-node here so we can use TypeScript for our Config Plugins + * and not have to compile them to JavaScript + */ +require("ts-node/register") + +/** + * @param config ExpoConfig coming from the static config app.json if it exists + * + * You can read more about Expo's Configuration Resolution Rules here: + * https://docs.expo.dev/workflow/configuration/#configuration-resolution-rules + */ +module.exports = ({ config }: ConfigContext): Partial => { + const existingPlugins = config.plugins ?? [] + + return { + ...config, + plugins: [...existingPlugins, require("./plugins/withSplashScreen").withSplashScreen], + } +} diff --git a/apps/mobile/app.json b/apps/mobile/app.json new file mode 100644 index 0000000..5a8213e --- /dev/null +++ b/apps/mobile/app.json @@ -0,0 +1,69 @@ +{ + "name": "latent-booking", + "displayName": "Latent Booking", + "expo": { + "name": "Latent Booking", + "slug": "latent-booking", + "scheme": "latent-booking", + "version": "1.0.0", + "orientation": "portrait", + "userInterfaceStyle": "automatic", + "icon": "./assets/images/app-icon-all.png", + "updates": { + "fallbackToCacheTimeout": 0 + }, + "newArchEnabled": false, + "jsEngine": "hermes", + "assetBundlePatterns": [ + "**/*" + ], + "android": { + "icon": "./assets/images/app-icon-android-legacy.png", + "package": "com.latentbooking", + "adaptiveIcon": { + "foregroundImage": "./assets/images/app-icon-android-adaptive-foreground.png", + "backgroundImage": "./assets/images/app-icon-android-adaptive-background.png" + }, + "splash": { + "backgroundColor": "#0A0A0A" + } + }, + "ios": { + "icon": "./assets/images/app-icon-ios.png", + "supportsTablet": true, + "bundleIdentifier": "com.latentbooking", + "splash": { + "backgroundColor": "#0A0A0A" + } + }, + "web": { + "favicon": "./assets/images/app-icon-web-favicon.png", + "bundler": "metro", + "splash": { + "backgroundColor": "#0A0A0A" + } + }, + "plugins": [ + "expo-localization", + "expo-font", + [ + "expo-splash-screen", + { + "image": "./assets/images/app-icon-android-adaptive-foreground.png", + "imageWidth": 300, + "resizeMode": "contain", + "backgroundColor": "#0A0A0A" + } + ] + ], + "experiments": { + "tsconfigPaths": true + }, + "splash": { + "backgroundColor": "#0A0A0A" + } + }, + "ignite": { + "version": "10.1.4" + } +} diff --git a/apps/mobile/app/app.tsx b/apps/mobile/app/app.tsx new file mode 100644 index 0000000..1b81951 --- /dev/null +++ b/apps/mobile/app/app.tsx @@ -0,0 +1,114 @@ +/* eslint-disable import/first */ +/** + * Welcome to the main entry point of the app. In this file, we'll + * be kicking off our app. + * + * Most of this file is boilerplate and you shouldn't need to modify + * it very often. But take some time to look through and understand + * what is going on here. + * + * The app navigation resides in ./app/navigators, so head over there + * if you're interested in adding screens and navigators. + */ +if (__DEV__) { + // Load Reactotron in development only. + // Note that you must be using metro's `inlineRequires` for this to work. + // If you turn it off in metro.config.js, you'll have to manually import it. + require("./devtools/ReactotronConfig.ts") +} +import "./utils/gestureHandler" +import { initI18n } from "./i18n" +import "./utils/ignoreWarnings" +import { useFonts } from "expo-font" +import { useEffect, useState } from "react" +import { initialWindowMetrics, SafeAreaProvider } from "react-native-safe-area-context" +import * as Linking from "expo-linking" +import * as SplashScreen from "expo-splash-screen" +import { AppNavigator } from "./navigators" +import { ErrorBoundary } from "./screens/ErrorScreen/ErrorBoundary" +// import * as storage from "./utils/storage" +import { customFontsToLoad } from "./theme" +import Config from "./config" +import { KeyboardProvider } from "react-native-keyboard-controller" +import { loadDateFnsLocale } from "./utils/formatDate" + +export const NAVIGATION_PERSISTENCE_KEY = "NAVIGATION_STATE" + +// Web linking configuration +const prefix = Linking.createURL("/") +const config = { + screens: { + Login: { + path: "", + }, + Welcome: "welcome", + Demo: { + screens: { + DemoShowroom: { + path: "showroom/:queryIndex?/:itemIndex?", + }, + DemoDebug: "debug", + DemoPodcastList: "podcast", + DemoCommunity: "community", + }, + }, + }, +} + +/** + * This is the root component of our app. + * @param {AppProps} props - The props for the `App` component. + * @returns {JSX.Element} The rendered `App` component. + */ +export function App() { + // const { + // initialNavigationState, + // onNavigationStateChange, + // isRestored: isNavigationStateRestored, + // } = useNavigationPersistence(storage, NAVIGATION_PERSISTENCE_KEY) + + const [areFontsLoaded, fontLoadError] = useFonts(customFontsToLoad) + const [isI18nInitialized, setIsI18nInitialized] = useState(false) + + useEffect(() => { + initI18n() + .then(() => setIsI18nInitialized(true)) + .then(() => loadDateFnsLocale()) + }, []) + + useEffect(() => { + // If your initialization scripts run very fast, it's good to show the splash screen for just a bit longer to prevent flicker. + // Slightly delaying splash screen hiding for better UX; can be customized or removed as needed, + setTimeout(SplashScreen.hideAsync, 500) + }, []) + + // Before we show the app, we have to wait for our state to be ready. + // In the meantime, don't render anything. This will be the background + // color set in native by rootView's background color. + // In iOS: application:didFinishLaunchingWithOptions: + // In Android: https://stackoverflow.com/a/45838109/204044 + // You can replace with your own loading component if you wish. + if (!isI18nInitialized || (!areFontsLoaded && !fontLoadError)) { + return null + } + + const linking = { + prefixes: [prefix], + config, + } + + // otherwise, we're ready to render the app + return ( + + + + + + + + ) +} diff --git a/apps/mobile/app/components/AutoImage.tsx b/apps/mobile/app/components/AutoImage.tsx new file mode 100644 index 0000000..d4dbd5b --- /dev/null +++ b/apps/mobile/app/components/AutoImage.tsx @@ -0,0 +1,89 @@ +import { useLayoutEffect, useState } from "react" +import { Image, ImageProps, ImageURISource, PixelRatio, Platform } from "react-native" + +export interface AutoImageProps extends ImageProps { + /** + * How wide should the image be? + */ + maxWidth?: number + /** + * How tall should the image be? + */ + maxHeight?: number + headers?: { + [key: string]: string + } +} + +/** + * A hook that will return the scaled dimensions of an image based on the + * provided dimensions' aspect ratio. If no desired dimensions are provided, + * it will return the original dimensions of the remote image. + * + * How is this different from `resizeMode: 'contain'`? Firstly, you can + * specify only one side's size (not both). Secondly, the image will scale to fit + * the desired dimensions instead of just being contained within its image-container. + * @param {number} remoteUri - The URI of the remote image. + * @param {number} dimensions - The desired dimensions of the image. If not provided, the original dimensions will be returned. + * @returns {[number, number]} - The scaled dimensions of the image. + */ +export function useAutoImage( + remoteUri: string, + headers?: { + [key: string]: string + }, + dimensions?: [maxWidth?: number, maxHeight?: number], +): [width: number, height: number] { + const [[remoteWidth, remoteHeight], setRemoteImageDimensions] = useState([0, 0]) + const remoteAspectRatio = remoteWidth / remoteHeight + const [maxWidth, maxHeight] = dimensions ?? [] + + useLayoutEffect(() => { + if (!remoteUri) return + + if (!headers) { + Image.getSize(remoteUri, (w, h) => setRemoteImageDimensions([w, h])) + } else { + Image.getSizeWithHeaders(remoteUri, headers, (w, h) => setRemoteImageDimensions([w, h])) + } + }, [remoteUri, headers]) + + if (Number.isNaN(remoteAspectRatio)) return [0, 0] + + if (maxWidth && maxHeight) { + const aspectRatio = Math.min(maxWidth / remoteWidth, maxHeight / remoteHeight) + return [ + PixelRatio.roundToNearestPixel(remoteWidth * aspectRatio), + PixelRatio.roundToNearestPixel(remoteHeight * aspectRatio), + ] + } else if (maxWidth) { + return [maxWidth, PixelRatio.roundToNearestPixel(maxWidth / remoteAspectRatio)] + } else if (maxHeight) { + return [PixelRatio.roundToNearestPixel(maxHeight * remoteAspectRatio), maxHeight] + } else { + return [remoteWidth, remoteHeight] + } +} + +/** + * An Image component that automatically sizes a remote or data-uri image. + * @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/app/components/AutoImage/} + * @param {AutoImageProps} props - The props for the `AutoImage` component. + * @returns {JSX.Element} The rendered `AutoImage` component. + */ +export function AutoImage(props: AutoImageProps) { + const { maxWidth, maxHeight, ...ImageProps } = props + const source = props.source as ImageURISource + const headers = source?.headers + + const [width, height] = useAutoImage( + Platform.select({ + web: (source?.uri as string) ?? (source as string), + default: source?.uri as string, + }), + headers, + [maxWidth, maxHeight], + ) + + return +} diff --git a/apps/mobile/app/components/Button.tsx b/apps/mobile/app/components/Button.tsx new file mode 100644 index 0000000..a255fbd --- /dev/null +++ b/apps/mobile/app/components/Button.tsx @@ -0,0 +1,248 @@ +import { ComponentType } from "react" +import { + Pressable, + PressableProps, + PressableStateCallbackType, + StyleProp, + TextStyle, + ViewStyle, +} from "react-native" + +import type { ThemedStyle, ThemedStyleArray } from "@/theme" +import { useAppTheme } from "@/utils/useAppTheme" + +import { $styles } from "../theme" +import { Text, TextProps } from "./Text" + +type Presets = "default" | "filled" | "reversed" + +export interface ButtonAccessoryProps { + style: StyleProp + pressableState: PressableStateCallbackType + disabled?: boolean +} + +export interface ButtonProps extends PressableProps { + /** + * Text which is looked up via i18n. + */ + tx?: TextProps["tx"] + /** + * The text to display if not using `tx` or nested components. + */ + text?: TextProps["text"] + /** + * Optional options to pass to i18n. Useful for interpolation + * as well as explicitly setting locale or translation fallbacks. + */ + txOptions?: TextProps["txOptions"] + /** + * An optional style override useful for padding & margin. + */ + style?: StyleProp + /** + * An optional style override for the "pressed" state. + */ + pressedStyle?: StyleProp + /** + * An optional style override for the button text. + */ + textStyle?: StyleProp + /** + * An optional style override for the button text when in the "pressed" state. + */ + pressedTextStyle?: StyleProp + /** + * An optional style override for the button text when in the "disabled" state. + */ + disabledTextStyle?: StyleProp + /** + * One of the different types of button presets. + */ + preset?: Presets + /** + * An optional component to render on the right side of the text. + * Example: `RightAccessory={(props) => }` + */ + RightAccessory?: ComponentType + /** + * An optional component to render on the left side of the text. + * Example: `LeftAccessory={(props) => }` + */ + LeftAccessory?: ComponentType + /** + * Children components. + */ + children?: React.ReactNode + /** + * disabled prop, accessed directly for declarative styling reasons. + * https://reactnative.dev/docs/pressable#disabled + */ + disabled?: boolean + /** + * An optional style override for the disabled state + */ + disabledStyle?: StyleProp +} + +/** + * A component that allows users to take actions and make choices. + * Wraps the Text component with a Pressable component. + * @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/app/components/Button/} + * @param {ButtonProps} props - The props for the `Button` component. + * @returns {JSX.Element} The rendered `Button` component. + * @example + *