├── src ├── types │ └── index.ts ├── api │ ├── index.tsx │ ├── common │ │ ├── index.tsx │ │ ├── client.tsx │ │ ├── api-provider.tsx │ │ └── utils.tsx │ ├── posts │ │ ├── types.ts │ │ ├── index.ts │ │ ├── use-post.ts │ │ ├── use-add-post.ts │ │ └── use-posts.ts │ └── types.ts ├── lib │ ├── hooks │ │ ├── index.tsx │ │ ├── use-is-first-time.tsx │ │ └── use-selected-theme.tsx │ ├── index.tsx │ ├── i18n │ │ ├── react-i18next.d.ts │ │ ├── resources.ts │ │ ├── types.ts │ │ ├── index.tsx │ │ └── utils.tsx │ ├── auth │ │ ├── utils.tsx │ │ └── index.tsx │ ├── storage.tsx │ ├── env.js │ ├── utils.ts │ ├── use-theme-config.tsx │ └── test-utils.tsx ├── components │ ├── ui │ │ ├── icons │ │ │ ├── index.tsx │ │ │ ├── caret-down.tsx │ │ │ ├── home.tsx │ │ │ ├── feed.tsx │ │ │ ├── arrow-right.tsx │ │ │ ├── website.tsx │ │ │ ├── share.tsx │ │ │ ├── style.tsx │ │ │ ├── support.tsx │ │ │ ├── rate.tsx │ │ │ ├── github.tsx │ │ │ ├── settings.tsx │ │ │ └── language.tsx │ │ ├── focus-aware-status-bar.tsx │ │ ├── image.tsx │ │ ├── index.tsx │ │ ├── text.tsx │ │ ├── progress-bar.tsx │ │ ├── utils.tsx │ │ ├── colors.js │ │ └── modal-keyboard-aware-scroll-view.tsx │ ├── title.tsx │ ├── settings │ │ ├── items-container.tsx │ │ ├── item.tsx │ │ ├── language-item.tsx │ │ └── theme-item.tsx │ ├── typography.tsx │ ├── colors.tsx │ ├── card.tsx │ ├── buttons.tsx │ ├── inputs.tsx │ ├── login-form.tsx │ └── login-form.test.tsx ├── app │ ├── [...messing].tsx │ ├── (app) │ │ ├── style.tsx │ │ ├── index.tsx │ │ ├── _layout.tsx │ │ └── settings.tsx │ ├── login.tsx │ ├── feed │ │ ├── [id].tsx │ │ └── add-post.tsx │ ├── onboarding.tsx │ ├── +html.tsx │ └── _layout.tsx └── translations │ ├── ar.json │ └── en.json ├── .husky ├── .gitignore ├── commit-msg ├── common.sh ├── post-merge └── pre-commit ├── .npmrc ├── android ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values-night │ │ │ │ │ └── colors.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ ├── ic_launcher_round.webp │ │ │ │ │ └── ic_launcher_foreground.webp │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ ├── ic_launcher_round.webp │ │ │ │ │ └── ic_launcher_foreground.webp │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ ├── ic_launcher_round.webp │ │ │ │ │ └── ic_launcher_foreground.webp │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ ├── ic_launcher_round.webp │ │ │ │ │ └── ic_launcher_foreground.webp │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.webp │ │ │ │ │ ├── ic_launcher_round.webp │ │ │ │ │ └── ic_launcher_foreground.webp │ │ │ │ ├── drawable-hdpi │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ ├── drawable-mdpi │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ ├── drawable-xxxhdpi │ │ │ │ │ └── splashscreen_logo.png │ │ │ │ ├── values │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── drawable │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ └── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── assets │ │ │ │ └── fonts │ │ │ │ │ └── Inter.ttf │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── obytes │ │ │ │ └── development │ │ │ │ ├── MainApplication.kt │ │ │ │ └── MainActivity.kt │ │ └── debug │ │ │ └── AndroidManifest.xml │ ├── debug.keystore │ └── proguard-rules.pro ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle ├── settings.gradle └── gradle.properties ├── nativewind-env.d.ts ├── docs ├── tsconfig.json ├── public │ ├── _redirects │ ├── og.jpg │ └── reviews │ │ ├── aman.jpg │ │ ├── brandon.png │ │ ├── kawtar.jpg │ │ ├── simon.jpg │ │ └── yuri.jpeg ├── src │ ├── env.d.ts │ ├── assets │ │ └── logo.webp │ ├── content │ │ ├── config.ts │ │ └── docs │ │ │ ├── reviews.md │ │ │ ├── changelog.md │ │ │ ├── guides │ │ │ ├── storage.mdx │ │ │ └── navigation.mdx │ │ │ ├── how-to-contribute.md │ │ │ ├── getting-started │ │ │ └── customize-app.mdx │ │ │ ├── stay-updated.md │ │ │ ├── ui-and-theme │ │ │ └── fonts.mdx │ │ │ ├── ci-cd │ │ │ └── overview.mdx │ │ │ ├── libraries-recommendation.md │ │ │ └── testing │ │ │ └── overview.mdx │ ├── components │ │ ├── code.astro │ │ ├── LastUpdated.astro │ │ └── Comments.astro │ └── styles │ │ └── custom.css ├── .gitignore ├── ec.config.mjs ├── package.json └── README.md ├── global.css ├── __mocks__ ├── @gorhom │ └── bottom-sheet.ts ├── react-native-gesture-handler.ts ├── react-native-keyboard-controller.ts ├── expo-localization.ts └── moti.ts ├── commitlint.config.js ├── assets ├── icon.png ├── favicon.png ├── fonts │ └── Inter.ttf ├── splash-icon.png └── adaptive-icon.png ├── .maestro ├── utils │ ├── hide-keyboard-android.yaml │ ├── hide-keyboard-ios.yaml │ ├── onboarding.yaml │ ├── onboarding-and-login.yaml │ ├── hide-keyboard.yaml │ └── login.yaml ├── auth │ ├── onboarding.yaml │ └── login-with-validation.yaml ├── config.yaml └── app │ ├── tabs.yaml │ └── create-post.yaml ├── ios ├── ObytesApp │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── SplashScreenLogo.imageset │ │ │ ├── image.png │ │ │ ├── image@2x.png │ │ │ ├── image@3x.png │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── App-Icon-1024x1024@1x.png │ │ │ └── Contents.json │ │ └── SplashScreenBackground.colorset │ │ │ └── Contents.json │ ├── ObytesApp-Bridging-Header.h │ ├── ObytesApp.entitlements │ ├── Supporting │ │ └── Expo.plist │ ├── PrivacyInfo.xcprivacy │ └── AppDelegate.swift ├── Podfile.properties.json ├── ObytesApp.xcworkspace │ └── contents.xcworkspacedata ├── .gitignore ├── .xcode.env └── Podfile ├── .prettierrc.js ├── jest-setup.ts ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── workflows │ ├── stale.yml │ ├── new-github-release.yml │ ├── compress-images.yml │ ├── lint-ts.yml │ ├── eas-build-prod.yml │ ├── test.yml │ ├── eas-build-qa.yml │ ├── expo-doctor.yml │ ├── type-check.yml │ ├── e2e-android-maestro.yml │ └── new-app-version.yml ├── scripts │ └── expo-doctor.sh └── actions │ ├── setup-node-pnpm-install │ └── action.yml │ └── setup-jdk-generate-apk │ └── action.yml ├── .env.development ├── .env.production ├── .env.staging ├── metro.config.js ├── scripts ├── genrate-apk-and-install └── i18next-syntax-validation.js ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── tailwind.config.js ├── lint-staged.config.js ├── tsconfig.json ├── prompts ├── expo-doctor.md └── svg-icon.md ├── babel.config.js ├── cli ├── package.json ├── index.js ├── clone-repo.js ├── utils.js ├── pnpm-lock.yaml └── setup-project.js ├── LICENSE ├── jest.config.js ├── eas.json ├── README-project.md └── app.config.ts /src/types/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | pnpm commitlint --edit $1 -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | node-linker=hoisted 2 | auto-install-peers=true -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nativewind-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict" 3 | } 4 | -------------------------------------------------------------------------------- /global.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /__mocks__/@gorhom/bottom-sheet.ts: -------------------------------------------------------------------------------- 1 | module.exports = require('@gorhom/bottom-sheet/mock'); 2 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ['@commitlint/config-conventional'] }; 2 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/assets/icon.png -------------------------------------------------------------------------------- /.maestro/utils/hide-keyboard-android.yaml: -------------------------------------------------------------------------------- 1 | appId: ${APP_ID} 2 | tags: 3 | - util 4 | --- 5 | - hideKeyboard -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/assets/favicon.png -------------------------------------------------------------------------------- /docs/public/_redirects: -------------------------------------------------------------------------------- 1 | # redirect all /docs requests to the root domain 2 | 3 | /docs/\* /:splat 301 4 | -------------------------------------------------------------------------------- /docs/public/og.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/public/og.jpg -------------------------------------------------------------------------------- /src/api/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './common'; 2 | export * from './posts'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /src/lib/hooks/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './use-is-first-time'; 2 | export * from './use-selected-theme'; 3 | -------------------------------------------------------------------------------- /docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /__mocks__/react-native-gesture-handler.ts: -------------------------------------------------------------------------------- 1 | module.exports = require('react-native-gesture-handler/src/mocks.ts'); 2 | -------------------------------------------------------------------------------- /__mocks__/react-native-keyboard-controller.ts: -------------------------------------------------------------------------------- 1 | module.exports = require('react-native-keyboard-controller/jest'); 2 | -------------------------------------------------------------------------------- /assets/fonts/Inter.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/assets/fonts/Inter.ttf -------------------------------------------------------------------------------- /assets/splash-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/assets/splash-icon.png -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/debug.keystore -------------------------------------------------------------------------------- /assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/assets/adaptive-icon.png -------------------------------------------------------------------------------- /docs/src/assets/logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/src/assets/logo.webp -------------------------------------------------------------------------------- /src/api/common/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './api-provider'; 2 | export * from './client'; 3 | export * from './utils'; 4 | -------------------------------------------------------------------------------- /docs/public/reviews/aman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/public/reviews/aman.jpg -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /docs/public/reviews/brandon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/public/reviews/brandon.png -------------------------------------------------------------------------------- /docs/public/reviews/kawtar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/public/reviews/kawtar.jpg -------------------------------------------------------------------------------- /docs/public/reviews/simon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/public/reviews/simon.jpg -------------------------------------------------------------------------------- /docs/public/reviews/yuri.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/docs/public/reviews/yuri.jpeg -------------------------------------------------------------------------------- /src/lib/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './auth'; 2 | export * from './hooks'; 3 | export * from './i18n'; 4 | export * from './utils'; 5 | -------------------------------------------------------------------------------- /.maestro/utils/hide-keyboard-ios.yaml: -------------------------------------------------------------------------------- 1 | appId: ${APP_ID} 2 | tags: 3 | - util 4 | --- 5 | - tapOn: 6 | id: "Return" # Keyboard Return -------------------------------------------------------------------------------- /src/api/posts/types.ts: -------------------------------------------------------------------------------- 1 | export type Post = { 2 | userId: number; 3 | id: number; 4 | title: string; 5 | body: string; 6 | }; 7 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "hermes", 3 | "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true", 4 | "newArchEnabled": "true" 5 | } 6 | -------------------------------------------------------------------------------- /src/api/posts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './use-add-post'; 3 | export * from './use-post'; 4 | export * from './use-posts'; 5 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Inter.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/assets/fonts/Inter.ttf -------------------------------------------------------------------------------- /ios/ObytesApp/ObytesApp-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /src/api/types.ts: -------------------------------------------------------------------------------- 1 | export type PaginateQuery = { 2 | results: T[]; 3 | count: number; 4 | next: string | null; 5 | previous: string | null; 6 | }; 7 | -------------------------------------------------------------------------------- /src/api/common/client.tsx: -------------------------------------------------------------------------------- 1 | import { Env } from '@env'; 2 | import axios from 'axios'; 3 | export const client = axios.create({ 4 | baseURL: Env.API_URL, 5 | }); 6 | -------------------------------------------------------------------------------- /__mocks__/expo-localization.ts: -------------------------------------------------------------------------------- 1 | export const locale = 'en-US'; 2 | export const locales = ['en-US']; 3 | export const timezone = 'UTC'; 4 | export const isRTL = false; 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('prettier').Config} */ 2 | const config = { 3 | singleQuote: true, 4 | endOfLine: 'auto', 5 | trailingComma: 'es5', 6 | }; 7 | 8 | module.exports = config; 9 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/image.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/image@2x.png -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obytes/react-native-template-obytes/HEAD/ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/image@3x.png -------------------------------------------------------------------------------- /jest-setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/react-native/extend-expect'; 2 | 3 | // react-hook form setup for testing 4 | // @ts-ignore 5 | global.window = {}; 6 | // @ts-ignore 7 | global.window = global; 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Summary: 2 | 3 | ## Steps to reproduce: 4 | 5 | ## Expected behavior: 6 | 7 | ## Additional notes: 8 | 9 | #### Tasks 10 | 11 | - [ ] Task 1 12 | - [ ] Task 2 13 | - [ ] Task 3 14 | -------------------------------------------------------------------------------- /.husky/common.sh: -------------------------------------------------------------------------------- 1 | command_exists() { 2 | command -v "$1" >/dev/null 2>&1 3 | } 4 | 5 | # Workaround for Windows 10, Git Bash and Yarn 6 | if command_exists winpty && test -t 1; then 7 | exec 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.maestro/config.yaml: -------------------------------------------------------------------------------- 1 | flows: 2 | - auth/* 3 | - app/* 4 | 5 | excludeTags: 6 | - util 7 | 8 | executionOrder: 9 | continueOnFailure: false # default is true 10 | flowsOrder: 11 | - onboarding 12 | - login-with-validation -------------------------------------------------------------------------------- /.maestro/utils/onboarding-and-login.yaml: -------------------------------------------------------------------------------- 1 | appId: ${APP_ID} 2 | tags: 3 | - util 4 | --- 5 | - runFlow: 6 | when: 7 | visible: "Obytes Starter" 8 | file: onboarding.yaml 9 | - runFlow: 10 | when: 11 | visible: Sign In 12 | file: login.yaml -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #2E3C4B 3 | #2E3C4B 4 | #023c69 5 | #2E3C4B 6 | -------------------------------------------------------------------------------- /src/lib/i18n/react-i18next.d.ts: -------------------------------------------------------------------------------- 1 | import type { resources } from './resources'; 2 | 3 | // react-i18next versions higher than 11.11.0 4 | 5 | declare module 'react-i18next' { 6 | interface CustomTypeOptions { 7 | resources: (typeof resources)['en']; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.maestro/utils/hide-keyboard.yaml: -------------------------------------------------------------------------------- 1 | appId: ${APP_ID} 2 | tags: 3 | - util 4 | --- 5 | - runFlow: 6 | when: 7 | platform: iOS 8 | file: ./hide-keyboard-ios.yaml 9 | - runFlow: 10 | when: 11 | platform: Android 12 | file: ./hide-keyboard-android.yaml -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | API_URL=https://dummyjson.com/ 2 | 3 | ## TODO: add the variable to your CI and remove it from here, not recommended setting sensitive values on your git repo 4 | SECRET_KEY=my-secret-key 5 | VAR_NUMBER=10 # this is a number variable 6 | VAR_BOOL=true # this is a boolean variable -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | API_URL=https://dummyjson.com/ 2 | 3 | ## TODO: add the variable to your CI and remove it from here, not recommended setting sensitive values on your git repo 4 | SECRET_KEY=my-secret-key 5 | VAR_NUMBER=10 # this is a number variable 6 | VAR_BOOL=true # this is a boolean variable -------------------------------------------------------------------------------- /.env.staging: -------------------------------------------------------------------------------- 1 | API_URL=https://dummyjson.com/ 2 | 3 | ## TODO: add the variable to your CI and remove it from here, not recommended setting sensitive values on your git repo 4 | SECRET_KEY=my-secret-key 5 | VAR_NUMBER=10 # this is a number variable 6 | VAR_BOOL=true # this is a boolean variable -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const { getDefaultConfig } = require('expo/metro-config'); 4 | const { withNativeWind } = require('nativewind/metro'); 5 | 6 | const config = getDefaultConfig(__dirname); 7 | 8 | module.exports = withNativeWind(config, { input: './global.css' }); 9 | -------------------------------------------------------------------------------- /scripts/genrate-apk-and-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # this simple script will get the latest build url for the android platform 3 | ./android/gradlew assembleRelease -p ./android # build debug apk 4 | find ./android -type f -name "app-release.apk" # find apk file 5 | adb install "" -------------------------------------------------------------------------------- /docs/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from 'astro:content'; 2 | import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | i18n: defineCollection({ type: 'data', schema: i18nSchema() }), 7 | }; 8 | -------------------------------------------------------------------------------- /src/lib/i18n/resources.ts: -------------------------------------------------------------------------------- 1 | import ar from '@/translations/ar.json'; 2 | import en from '@/translations/en.json'; 3 | 4 | export const resources = { 5 | en: { 6 | translation: en, 7 | }, 8 | ar: { 9 | translation: ar, 10 | }, 11 | }; 12 | 13 | export type Language = keyof typeof resources; 14 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /ios/ObytesApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "App-Icon-1024x1024@1x.png", 5 | "idiom": "universal", 6 | "platform": "ios", 7 | "size": "1024x1024" 8 | } 9 | ], 10 | "info": { 11 | "version": 1, 12 | "author": "expo" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/src/content/docs/reviews.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: What people say about the starter 3 | description: What people say about the starter 4 | head: 5 | - tag: title 6 | content: Reviews | React Native / Expo Starter 7 | --- 8 | 9 | This is a list of reviews from people who have used the starter kit. 10 | 11 | Please feel free to add your in the comments section 👇 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | dist/ 4 | npm-debug.* 5 | *.jks 6 | *.p8 7 | *.p12 8 | *.key 9 | *.mobileprovision 10 | *.orig.* 11 | web-build/ 12 | yarn-error.log 13 | /coverage 14 | # macOS 15 | .DS_Store 16 | 17 | # @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb 18 | # The following patterns were generated by expo-cli 19 | 20 | expo-env.d.ts 21 | # @end expo-cli -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ObytesApp 3 | automatic 4 | contain 5 | false 6 | -------------------------------------------------------------------------------- /src/components/ui/icons/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './arrow-right'; 2 | export * from './caret-down'; 3 | export * from './feed'; 4 | export * from './github'; 5 | export * from './home'; 6 | export * from './language'; 7 | export * from './rate'; 8 | export * from './settings'; 9 | export * from './share'; 10 | export * from './style'; 11 | export * from './support'; 12 | export * from './website'; 13 | -------------------------------------------------------------------------------- /docs/src/content/docs/changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CHANGELOG 3 | description: New features, improvements, and bug fixes for the React Native / Expo Starter. 4 | head: 5 | - tag: title 6 | content: Obytes Starter ChangeLog | React Native / Expo Starter 7 | --- 8 | 9 | For complete changelog, please check the [GitHub releases](https://github.com/obytes/react-native-template-obytes/releases) page. 10 | -------------------------------------------------------------------------------- /src/lib/auth/utils.tsx: -------------------------------------------------------------------------------- 1 | import { getItem, removeItem, setItem } from '@/lib/storage'; 2 | 3 | const TOKEN = 'token'; 4 | 5 | export type TokenType = { 6 | access: string; 7 | refresh: string; 8 | }; 9 | 10 | export const getToken = () => getItem(TOKEN); 11 | export const removeToken = () => removeItem(TOKEN); 12 | export const setToken = (value: TokenType) => setItem(TOKEN, value); 13 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/ObytesApp/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | 12 | -------------------------------------------------------------------------------- /src/components/title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { Text, View } from '@/components/ui'; 4 | 5 | type Props = { 6 | text: string; 7 | }; 8 | export const Title = ({ text }: Props) => { 9 | return ( 10 | 11 | {text} 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /.maestro/app/tabs.yaml: -------------------------------------------------------------------------------- 1 | appId: ${APP_ID} 2 | env: 3 | Name: 'User' 4 | EMAIL: 'user@test.com' 5 | PASSWORD: 'password' 6 | --- 7 | - launchApp 8 | - runFlow: ../utils/onboarding-and-login.yaml 9 | - assertVisible: 'Feed' 10 | - assertVisible: 11 | id: 'style-tab' 12 | - tapOn: 13 | id: 'style-tab' 14 | - assertVisible: 'Typography' 15 | - tapOn: 16 | id: 'settings-tab' 17 | - assertVisible: 'Settings' 18 | - scroll 19 | - assertVisible: 'Logout' 20 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | .xcode.env.local 25 | 26 | # Bundle artifacts 27 | *.jsbundle 28 | 29 | # CocoaPods 30 | /Pods/ 31 | -------------------------------------------------------------------------------- /src/lib/hooks/use-is-first-time.tsx: -------------------------------------------------------------------------------- 1 | import { useMMKVBoolean } from 'react-native-mmkv'; 2 | 3 | import { storage } from '../storage'; 4 | 5 | const IS_FIRST_TIME = 'IS_FIRST_TIME'; 6 | 7 | export const useIsFirstTime = () => { 8 | const [isFirstTime, setIsFirstTime] = useMMKVBoolean(IS_FIRST_TIME, storage); 9 | if (isFirstTime === undefined) { 10 | return [true, setIsFirstTime] as const; 11 | } 12 | return [isFirstTime, setIsFirstTime] as const; 13 | }; 14 | -------------------------------------------------------------------------------- /src/lib/storage.tsx: -------------------------------------------------------------------------------- 1 | import { MMKV } from 'react-native-mmkv'; 2 | 3 | export const storage = new MMKV(); 4 | 5 | export function getItem(key: string): T | null { 6 | const value = storage.getString(key); 7 | return value ? JSON.parse(value) || null : null; 8 | } 9 | 10 | export async function setItem(key: string, value: T) { 11 | storage.set(key, JSON.stringify(value)); 12 | } 13 | 14 | export async function removeItem(key: string) { 15 | storage.delete(key); 16 | } 17 | -------------------------------------------------------------------------------- /.husky/post-merge: -------------------------------------------------------------------------------- 1 | 2 | 3 | function changed { 4 | git diff --name-only HEAD@{1} HEAD | grep "^$1" >/dev/null 2>&1 5 | } 6 | 7 | echo 'Checking for changes in pnpm-lock.yml...' 8 | 9 | if changed 'pnpm-lock.yml'; then 10 | echo "📦 pnpm-lock.yml changed. Run pnpm install to bring your dependencies up to date." 11 | pnpm install 12 | fi 13 | 14 | echo 'You are up to date :)' 15 | 16 | echo 'If necessary, you can run pnpm prebuild to generate native code.' 17 | 18 | exit 0 19 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "yoavbls.pretty-ts-errors", 6 | "mikestead.dotenv", 7 | "eamodio.gitlens", 8 | "streetsidesoftware.code-spell-checker", 9 | "formulahendry.auto-close-tag", 10 | "formulahendry.auto-rename-tag", 11 | "bradlc.vscode-tailwindcss", 12 | "lokalise.i18n-ally", 13 | "wesbos.theme-cobalt2", 14 | "ChakrounAnas.turbo-console-log" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/SplashScreenBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "color": { 5 | "components": { 6 | "alpha": "1.000", 7 | "blue": "0.294117647058824", 8 | "green": "0.235294117647059", 9 | "red": "0.180392156862745" 10 | }, 11 | "color-space": "srgb" 12 | }, 13 | "idiom": "universal" 14 | } 15 | ], 16 | "info": { 17 | "version": 1, 18 | "author": "expo" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.maestro/utils/login.yaml: -------------------------------------------------------------------------------- 1 | appId: ${APP_ID} 2 | env: 3 | Name: "User" 4 | EMAIL: "user@test.com" 5 | PASSWORD: "password" 6 | tags: 7 | - util 8 | --- 9 | - tapOn: 10 | id: "name" 11 | - inputText: ${Name} 12 | - tapOn: 13 | id: "email-input" 14 | - inputText: ${EMAIL} 15 | - runFlow: ../utils/hide-keyboard.yaml 16 | - tapOn: 17 | id: "password-input" 18 | - inputText: ${PASSWORD} 19 | - runFlow: ../utils/hide-keyboard.yaml 20 | - tapOn: 21 | id: "login-button" 22 | - assertVisible: "Typography" 23 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const colors = require('./src/components/ui/colors'); 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | // NOTE: Update this to include the paths to all of your component files. 6 | content: ['./src/**/*.{js,jsx,ts,tsx}'], 7 | presets: [require('nativewind/preset')], 8 | darkMode: 'class', 9 | theme: { 10 | extend: { 11 | fontFamily: { 12 | inter: ['Inter'], 13 | }, 14 | colors, 15 | }, 16 | }, 17 | plugins: [], 18 | }; 19 | -------------------------------------------------------------------------------- /docs/ec.config.mjs: -------------------------------------------------------------------------------- 1 | import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections'; 2 | import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'; 3 | 4 | /** @type {import('@astrojs/starlight/expressive-code').StarlightExpressiveCodeOptions} */ 5 | export default { 6 | // Example: Using a custom plugin (which makes this `ec.config.mjs` file necessary) 7 | // plugins: [pluginCollapsibleSections(), pluginLineNumbers()], 8 | // ... any other options you want to configure 9 | }; 10 | -------------------------------------------------------------------------------- /ios/ObytesApp/Images.xcassets/SplashScreenLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "filename": "image@2x.png", 11 | "scale": "2x" 12 | }, 13 | { 14 | "idiom": "universal", 15 | "filename": "image@3x.png", 16 | "scale": "3x" 17 | } 18 | ], 19 | "info": { 20 | "version": 1, 21 | "author": "expo" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '**/*.{js,jsx,ts,tsx}': (filenames) => [ 3 | `npx eslint --fix ${filenames 4 | .map((filename) => `"${filename}"`) 5 | .join(' ')}`, 6 | ], 7 | '**/*.(md|json)': (filenames) => 8 | `npx prettier --write ${filenames 9 | .map((filename) => `"${filename}"`) 10 | .join(' ')}`, 11 | 'src/translations/*.(json)': (filenames) => [ 12 | `npx eslint --fix ${filenames 13 | .map((filename) => `"${filename}"`) 14 | .join(' ')}`, 15 | ], 16 | }; 17 | -------------------------------------------------------------------------------- /src/api/posts/use-post.ts: -------------------------------------------------------------------------------- 1 | import type { AxiosError } from 'axios'; 2 | import { createQuery } from 'react-query-kit'; 3 | 4 | import { client } from '../common'; 5 | import type { Post } from './types'; 6 | 7 | type Variables = { id: string }; 8 | type Response = Post; 9 | 10 | export const usePost = createQuery({ 11 | queryKey: ['posts'], 12 | fetcher: (variables) => { 13 | return client 14 | .get(`posts/${variables.id}`) 15 | .then((response) => response.data); 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /src/api/common/api-provider.tsx: -------------------------------------------------------------------------------- 1 | import { useReactQueryDevTools } from '@dev-plugins/react-query'; 2 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 3 | import * as React from 'react'; 4 | 5 | export const queryClient = new QueryClient(); 6 | 7 | export function APIProvider({ children }: { children: React.ReactNode }) { 8 | useReactQueryDevTools(queryClient); 9 | return ( 10 | // Provide the client to your App 11 | {children} 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/ui/icons/caret-down.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import type { SvgProps } from 'react-native-svg'; 3 | import Svg, { Path } from 'react-native-svg'; 4 | 5 | export const CaretDown = ({ ...props }: SvgProps) => ( 6 | 13 | 19 | 20 | ); 21 | -------------------------------------------------------------------------------- /src/api/posts/use-add-post.ts: -------------------------------------------------------------------------------- 1 | import type { AxiosError } from 'axios'; 2 | import { createMutation } from 'react-query-kit'; 3 | 4 | import { client } from '../common'; 5 | import type { Post } from './types'; 6 | 7 | type Variables = { title: string; body: string; userId: number }; 8 | type Response = Post; 9 | 10 | export const useAddPost = createMutation({ 11 | mutationFn: async (variables) => 12 | client({ 13 | url: 'posts/add', 14 | method: 'POST', 15 | data: variables, 16 | }).then((response) => response.data), 17 | }); 18 | -------------------------------------------------------------------------------- /src/api/posts/use-posts.ts: -------------------------------------------------------------------------------- 1 | import type { AxiosError } from 'axios'; 2 | import { createQuery } from 'react-query-kit'; 3 | 4 | import { client } from '../common'; 5 | import type { Post } from './types'; 6 | 7 | type Response = Post[]; 8 | type Variables = void; // as react-query-kit is strongly typed, we need to specify the type of the variables as void in case we don't need them 9 | 10 | export const usePosts = createQuery({ 11 | queryKey: ['posts'], 12 | fetcher: () => { 13 | return client.get(`posts`).then((response) => response.data.posts); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # react-native-reanimated 11 | -keep class com.swmansion.reanimated.** { *; } 12 | -keep class com.facebook.react.turbomodule.** { *; } 13 | 14 | # Add any project specific keep options here: 15 | -------------------------------------------------------------------------------- /src/app/[...messing].tsx: -------------------------------------------------------------------------------- 1 | import { Link, Stack } from 'expo-router'; 2 | 3 | import { Text, View } from '@/components/ui'; 4 | 5 | export default function NotFoundScreen() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | This screen doesn't exist. 12 | 13 | 14 | 15 | Go to home screen! 16 | 17 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /src/components/settings/items-container.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Text, View } from '@/components/ui'; 4 | import type { TxKeyPath } from '@/lib'; 5 | 6 | type Props = { 7 | children: React.ReactNode; 8 | title?: TxKeyPath; 9 | }; 10 | 11 | export const ItemsContainer = ({ children, title }: Props) => { 12 | return ( 13 | <> 14 | {title && } 15 | { 16 | 17 | {children} 18 | 19 | } 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | -------------------------------------------------------------------------------- /src/lib/env.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file should not be modified; use `env.js` in the project root to add your client environment variables. 3 | * If you import `Env` from `@env`, this is the file that will be loaded. 4 | * You can only access the client environment variables here. 5 | * NOTE: We use js file so we can load the client env types 6 | */ 7 | 8 | import Constants from 'expo-constants'; 9 | /** 10 | * @type {typeof import('../../env.js').ClientEnv} 11 | */ 12 | //@ts-ignore // Don't worry about TypeScript here; we know we're passing the correct environment variables to `extra` in `app.config.ts`. 13 | export const Env = Constants.expoConfig?.extra ?? {}; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo/tsconfig.base", 3 | "compilerOptions": { 4 | "strict": true, 5 | "baseUrl": ".", 6 | "paths": { 7 | "@/*": ["./src/*"], 8 | "@env": ["./src/lib/env.js"] 9 | }, 10 | "esModuleInterop": true, 11 | "checkJs": true 12 | }, 13 | "exclude": [ 14 | "node_modules", 15 | "babel.config.js", 16 | "metro.config.js", 17 | "docs", 18 | "cli", 19 | "android", 20 | "ios", 21 | "lint-staged.config.js" 22 | ], 23 | "include": [ 24 | "**/*.ts", 25 | "**/*.tsx", 26 | ".expo/types/**/*.ts", 27 | "expo-env.d.ts", 28 | "nativewind-env.d.ts" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## What does this do? 2 | 3 | 6 | 7 | ## Why did you do this? 8 | 9 | 12 | 13 | ## Who/what does this impact? 14 | 15 | 18 | 19 | ## How did you test this? 20 | 21 | 24 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | 2 | . "$(dirname "$0")/common.sh" 3 | 4 | 5 | echo "===\n>> Checking branch name..." 6 | 7 | # Check if branch protection is enabled 8 | if [[ -z $SKIP_BRANCH_PROTECTION ]]; then 9 | BRANCH=$(git rev-parse --abbrev-ref HEAD) 10 | PROTECTED_BRANCHES="^(main|master)" 11 | 12 | if [[ $BRANCH =~ $PROTECTED_BRANCHES ]]; then 13 | echo ">> Direct commits to the $BRANCH branch are not allowed. Please choose a new branch name." 14 | exit 1 15 | fi 16 | else 17 | echo ">> Skipping branch protection." 18 | fi 19 | 20 | echo ">> Finish checking branch name" 21 | echo ">> Linting your files and fixing them if needed..." 22 | 23 | pnpm type-check 24 | pnpm lint-staged -------------------------------------------------------------------------------- /docs/src/components/code.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Code as SCode } from '@astrojs/starlight/components' 3 | 4 | import fs from 'node:fs/promises'; 5 | 6 | interface Props { 7 | file: string; 8 | language?: string; 9 | meta?: string; 10 | } 11 | 12 | const { file, language, meta } = Astro.props; 13 | const fileNamePath = '../' + file; 14 | const fileEtension = file.split('.').pop() ?? 'js'; 15 | const code = await fs.readFile(fileNamePath, 'utf-8'); 16 | const lang = language ?? fileEtension; 17 | const metaa = `title="${file}"` + (meta ? ` ${meta}` : '') 18 | 19 | 20 | --- 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /prompts/expo-doctor.md: -------------------------------------------------------------------------------- 1 | You are an expert in TypeScript, Expo, and React Native. 2 | 3 | You are given a React Native project and you are tasked with fixing the project dependencies. 4 | 5 | You should follow the following steps: 6 | 7 | 1. Run expo doctor command using `pnpm run doctor` 8 | 2. Analyze the check results and provide an explanation of what we need to do to fix the issues 9 | 3. Run commands to fix the issues in case there are any 10 | 4. Run expo doctor command again to check if the issues are fixed 11 | 5. If the issues is fixed, make sure to commit changes for package.json and pnpm-lock.yaml with the message `git add package.json pnpm-lock.yaml && git commit -m "fix(deps): expo doctor issues"` 12 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ossified-orbit", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "@astrojs/starlight": "^0.31.1", 14 | "@expressive-code/plugin-collapsible-sections": "^0.33.4", 15 | "@expressive-code/plugin-line-numbers": "^0.33.4", 16 | "@fontsource/ibm-plex-mono": "^5.0.8", 17 | "@fontsource/ibm-plex-serif": "^5.0.8", 18 | "astro": "^5.1.10", 19 | "hast-util-to-html": "^9.0.0", 20 | "sharp": "^0.32.3", 21 | "starlight-llms-txt": "^0.4.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/src/components/LastUpdated.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { Props } from '@astrojs/starlight/props'; 3 | import Default from '@astrojs/starlight/components/LastUpdated.astro'; 4 | import Comments from './Comments.astro'; 5 | 6 | const { lastUpdated } = Astro.props; 7 | 8 | --- 9 | 10 | { 11 | lastUpdated && ( 12 |
13 |
14 | 15 |
16 | 17 |
18 | ) 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/components/ui/icons/home.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import type { SvgProps } from 'react-native-svg'; 3 | import Svg, { Path } from 'react-native-svg'; 4 | 5 | export function Home({ color = '#000', ...props }: SvgProps) { 6 | return ( 7 | 8 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/components/ui/focus-aware-status-bar.tsx: -------------------------------------------------------------------------------- 1 | import { useIsFocused } from '@react-navigation/native'; 2 | import { useColorScheme } from 'nativewind'; 3 | import * as React from 'react'; 4 | import { Platform } from 'react-native'; 5 | import { SystemBars } from 'react-native-edge-to-edge'; 6 | 7 | type Props = { hidden?: boolean }; 8 | export const FocusAwareStatusBar = ({ hidden = false }: Props) => { 9 | const isFocused = useIsFocused(); 10 | const { colorScheme } = useColorScheme(); 11 | 12 | if (Platform.OS === 'web') return null; 13 | 14 | return isFocused ? ( 15 |