diff --git a/.editorconfig b/.editorconfig index 79fe802..6e87a00 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,13 @@ +# Editor configuration, see http://editorconfig.org root = true [*] +charset = utf-8 indent_style = space indent_size = 2 -end_of_line = lf -charset = utf-8 insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..baa2bec --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..fc76cab --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,81 @@ +module.exports = { + extends: [ + 'airbnb', + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + ], + ignorePatterns: [ + 'dist/*', + 'plugins/*', + 'tests/*', + '/*.cjs', + '/*.js', + '/**/*.test.ts', + 'test/*', + ], + parser: '@typescript-eslint/parser', + settings: { + 'import/resolver': { + typescript: { + project: './tsconfig.json', + }, + }, + }, + plugins: ['@typescript-eslint', 'import', 'prettier'], + rules: { + 'no-underscore-dangle': 'off', + '@typescript-eslint/no-explicit-any': 'off', + 'no-console': 'off', + '@typescript-eslint/no-this-alias': 'off', + 'import/prefer-default-export': 'off', + '@typescript-eslint/no-empty-function': 'off', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': ['error'], + 'no-restricted-syntax': 'off', + 'import/no-unresolved': ['error', { ignore: ['^virtual:'] }], + 'consistent-return': 'off', + 'no-continue': 'off', + 'no-eval': 'off', + 'no-await-in-loop': 'off', + 'no-nested-ternary': 'off', + 'no-param-reassign': ['error', { props: false }], + 'prefer-destructuring': 'off', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'import/extensions': [ + 'error', + 'ignorePackages', + { + ts: 'never', + tsx: 'never', + }, + ], + 'import/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + ['sibling', 'parent'], + 'index', + 'unknown', + ], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + }, + ], + 'sort-imports': [ + 'error', + { + ignoreCase: false, + ignoreDeclarationSort: true, + ignoreMemberSort: false, + memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], + allowSeparatedGroups: true, + }, + ], + }, +}; diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7458772..05217f0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @movie-web/project-leads +* @movie-web/core diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..7e4576d --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Supported Versions + +The movie-web maintainers only support the latest version of movie-web published at https://movie-web.app. +This published version is equivalent to the master branch. + +Support is not provided for any forks or mirrors of movie-web. + +## Reporting a Vulnerability + +There are two ways you can contact the movie-web maintainers to report a vulnerability: + +- Email [security@movie-web.app](mailto:security@movie-web.app) +- Report the vulnerability in the [movie-web Discord server](https://discord.movie-web.app) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..6a115ea --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,6 @@ +This pull request resolves #XXX + +- [ ] I have read and agreed to the [code of conduct](https://github.com/movie-web/movie-web/blob/dev/.github/CODE_OF_CONDUCT.md). +- [ ] I have read and complied with the [contributing guidelines](https://github.com/movie-web/movie-web/blob/dev/.github/CONTRIBUTING.md). +- [ ] What I'm implementing was assigned to me and is an [approved issue](https://github.com/movie-web/movie-web/issues?q=is%3Aopen+is%3Aissue+label%3Aapproved). For reference, please take a look at our [GitHub projects](https://github.com/movie-web/movie-web/projects). +- [ ] I have tested all of my changes. diff --git a/.github/workflows/build-mobile.yml b/.github/workflows/build-mobile.yml new file mode 100644 index 0000000..49293f8 --- /dev/null +++ b/.github/workflows/build-mobile.yml @@ -0,0 +1,143 @@ +name: build mobile app + +on: + push: + branches: + - master + workflow_dispatch: + +permissions: + contents: write + +jobs: + build-android: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 21 + + - uses: pnpm/action-setup@v2 + name: Install pnpm + with: + version: 8 + run_install: false + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Install dependencies + run: pnpm install + + - name: Build native Android modules + run: pnpm exec nx run mobile:prebuild --platform=android + + - name: Build Android app + run: cd apps/mobile/android && ./gradlew assembleRelease + + - name: Rename apk + run: mv apps/mobile/android/app/build/outputs/apk/release/app-release.apk apps/mobile/android/app/build/outputs/apk/release/movie-web.apk + + - name: Upload movie-web.apk as artifact + uses: actions/upload-artifact@v4 + with: + name: apk + path: ./apps/mobile/android/app/build/outputs/apk/release/movie-web.apk + + build-ios: + runs-on: macos-13 + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Xcode Select Version + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '15.1.0' + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 21 + + - uses: pnpm/action-setup@v2 + name: Install pnpm + with: + version: 8 + run_install: false + + - name: Install dependencies + run: pnpm install + + - name: Build native iOS modules + run: pnpm exec nx run mobile:prebuild --platform=ios + + - name: Build iOS app + run: cd apps/mobile/ios && xcodebuild archive -workspace movieweb.xcworkspace -scheme "movieweb" -sdk iphoneos -configuration "Release" -archivePath "build/app.xcarchive" -destination generic/platform=iOS CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO + + - name: Export .ipa from .xcarchive + run: | + mv apps/mobile/ios/build/app.xcarchive/Products/Applications apps/mobile/ios/build/app.xcarchive/Products/Payload + cd apps/mobile/ios/build/app.xcarchive/Products + zip -r ../../movie-web.ipa Payload + + - name: Upload movie-web.ipa as artifact + uses: actions/upload-artifact@v4 + with: + name: ipa + path: ./apps/mobile/ios/build/movie-web.ipa + + release-app: + runs-on: ubuntu-latest + needs: [build-android, build-ios] + if: github.ref == 'refs/heads/master' + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Automated Version Bump + uses: phips28/gh-action-bump-version@v10.1.1 + with: + skip-tag: 'true' + commit-message: 'chore: bump version to {{version}} [skip ci]' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PACKAGEJSON_DIR: 'apps/mobile' + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + merge-multiple: true + + - name: Get package version + id: package-version + uses: martinbeentjes/npm-get-version-action@v1.3.1 + with: + path: apps/mobile + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + tag_name: v${{ steps.package-version.outputs.current-version }} + files: | + movie-web.apk + movie-web.ipa + fail_on_unmatched_files: true + token: ${{ env.GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..479346c --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +dist +tmp +/out-tsc + +# dependencies +node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +.nx/cache + +# Expo +node_modules/ +.expo/ +.yarn/ +dist/ +npm-debug.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +web-build/ +cache/ + + +apps/mobile-e2e/artifacts diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..c07a71c --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +strict-peer-dependencies=false +auto-install-peers=true +node-linker=hoisted diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..d4c3d32 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.10 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d155fdb --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..3a1180c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode", + "firsttris.vscode-jest-runner" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5d671d5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "eslint.format.enable": true, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + } +} diff --git a/README.md b/README.md index 7bfd381..700a597 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,70 @@ -# native-app +# movie-web native-app -The native app version of movie-web +Native-app for movie-web. -> [!IMPORTANT] -> This is work in progress, not even remotely close to being ready for use. +## Getting started + +```bash +pnpm install + +// Having nx installed globally is recommended +pnpm install -g nx + +// If you don't want nx installed globally, you can use the following command +(pnpm exec or npx) nx +``` + +## Running tasks + +To execute tasks with Nx use the following syntax: + +```bash +nx <...options> +``` + +For example, to run the mobile app: + +### Android + +```bash +nx run mobile:android +``` + +### iOS + +```bash +nx run mobile:ios +``` + +## Building archives + +### Android .apk + +```bash +nx run mobile:prebuild --platform=android +cd apps/mobile/android && ./gradlew assembleRelease +``` + +### iOS .app + +#### Real device + +```bash +nx run mobile:prebuild --platform=ios +cd apps/mobile/ios && xcodebuild archive -workspace movieweb.xcworkspace -scheme "movieweb" -sdk iphoneos -configuration "Release" -archivePath "build/app.xcarchive" -destination generic/platform=iOS CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO +``` + +#### Simulator + +```bash +nx run mobile:prebuild --platform=ios +cd apps/mobile/ios && xcodebuild archive -workspace movieweb.xcworkspace -scheme "movieweb" -sdk iphonesimulator -configuration "Release" -archivePath "build/app.xcarchive" -destination "generic/platform=iOS Simulator" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO +``` + +## Repository information + +This project uses Nx to manage the monorepo. For more information about Nx, visit [nx.dev](https://nx.dev). + +### Mobile app + +The mobile app is built with React Native and Expo. For more information about Expo, visit [expo.io](https://expo.io). diff --git a/apps/mobile-e2e/.babelrc b/apps/mobile-e2e/.babelrc new file mode 100644 index 0000000..990a2a8 --- /dev/null +++ b/apps/mobile-e2e/.babelrc @@ -0,0 +1,11 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + }, + ], + ], + "plugins": [], +} diff --git a/apps/mobile-e2e/.detoxrc.json b/apps/mobile-e2e/.detoxrc.json new file mode 100644 index 0000000..71555ad --- /dev/null +++ b/apps/mobile-e2e/.detoxrc.json @@ -0,0 +1,89 @@ +{ + "testRunner": { + "args": { + "$0": "jest", + "config": "./jest.config.json" + }, + "jest": { + "setupTimeout": 120000 + } + }, + "apps": { + "ios.debug": { + "type": "ios.app", + "build": "cd ../../apps/mobile/ios && xcodebuild -workspace movieweb.xcworkspace -scheme movieweb -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet", + "binaryPath": "../../apps/mobile/ios/build/Build/Products/Debug-iphonesimulator/movieweb.app" + }, + "ios.release": { + "type": "ios.app", + "build": "cd ../../apps/mobile/ios && xcodebuild -workspace movieweb.xcworkspace -scheme movieweb -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet", + "binaryPath": "../../apps/mobile/ios/build/Build/Products/Release-iphonesimulator/movieweb.app" + }, + + "ios.local": { + "type": "ios.app", + "build": "pnpm exec nx run mobile:build --platform ios --profile preview --wait --local --no-interactive --output=../../apps/mobile/dist/movieweb.tar.gz", + "binaryPath": "../../apps/mobile/dist/movieweb.app" + }, + + "android.debug": { + "type": "android.apk", + "build": "cd ../../apps/mobile/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug", + "binaryPath": "../../apps/mobile/android/app/build/outputs/apk/debug/app-debug.apk" + }, + "android.release": { + "type": "android.apk", + "build": "cd ../../apps/mobile/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release", + "binaryPath": "../../apps/mobile/android/app/build/outputs/apk/release/app-release.apk" + }, + + "android.local": { + "type": "android.apk", + "build": "pnpm exec nx run mobile:build --platform android --profile preview --wait --local --no-interactive --output=../../apps/mobile/dist/movieweb.apk", + "binaryPath": "../../apps/mobile/dist/movieweb.apk" + } + }, + "devices": { + "simulator": { + "type": "ios.simulator", + "device": { + "type": "iPhone 14" + } + }, + "emulator": { + "type": "android.emulator", + "device": { + "avdName": "Pixel_4a_API_30" + } + } + }, + "configurations": { + "ios.sim.release": { + "device": "simulator", + "app": "ios.release" + }, + "ios.sim.debug": { + "device": "simulator", + "app": "ios.debug" + }, + + "ios.sim.local": { + "device": "simulator", + "app": "ios.local" + }, + + "android.emu.release": { + "device": "emulator", + "app": "android.release" + }, + "android.emu.debug": { + "device": "emulator", + "app": "android.debug" + }, + + "android.emu.local": { + "device": "emulator", + "app": "android.local" + } + } +} diff --git a/apps/mobile-e2e/.eslintrc.json b/apps/mobile-e2e/.eslintrc.json new file mode 100644 index 0000000..d3e61a2 --- /dev/null +++ b/apps/mobile-e2e/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.js"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/mobile-e2e/jest.config.json b/apps/mobile-e2e/jest.config.json new file mode 100644 index 0000000..4dd11da --- /dev/null +++ b/apps/mobile-e2e/jest.config.json @@ -0,0 +1,22 @@ +{ + "preset": "../../jest.preset", + "rootDir": ".", + "testMatch": [ + "/src/**/*.test.ts?(x)", + "/src/**/*.spec.ts?(x)" + ], + "testTimeout": 120000, + "maxWorkers": 1, + "globalSetup": "detox/runners/jest/globalSetup", + "globalTeardown": "detox/runners/jest/globalTeardown", + "reporters": ["detox/runners/jest/reporter"], + "testEnvironment": "detox/runners/jest/testEnvironment", + "verbose": true, + "setupFilesAfterEnv": ["/test-setup.ts"], + "transform": { + "^.+\\.(ts|js|html)$": [ + "ts-jest", + { "tsconfig": "/tsconfig.e2e.json" } + ] + } +} diff --git a/apps/mobile-e2e/project.json b/apps/mobile-e2e/project.json new file mode 100644 index 0000000..39175eb --- /dev/null +++ b/apps/mobile-e2e/project.json @@ -0,0 +1,76 @@ +{ + "name": "mobile-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/mobile-e2e/src", + "projectType": "application", + "targets": { + "build-ios": { + "executor": "@nx/detox:build", + "options": { + "detoxConfiguration": "ios.sim.local" + }, + "configurations": { + "bare": { + "detoxConfiguration": "ios.sim.debug" + }, + "production": { + "detoxConfiguration": "ios.sim.release" + } + } + }, + "test-ios": { + "executor": "@nx/detox:test", + "options": { + "detoxConfiguration": "ios.sim.local", + "buildTarget": "mobile-e2e:build-ios" + }, + "configurations": { + "bare": { + "detoxConfiguration": "ios.sim.debug", + "buildTarget": "mobile-e2e:build-ios:bare" + }, + "production": { + "detoxConfiguration": "ios.sim.release", + "buildTarget": "mobile-e2e:build-ios:production" + } + } + }, + "build-android": { + "executor": "@nx/detox:build", + "options": { + "detoxConfiguration": "android.emu.local" + }, + "configurations": { + "bare": { + "detoxConfiguration": "android.emu.debug" + }, + "production": { + "detoxConfiguration": "android.emu.release" + } + } + }, + "test-android": { + "executor": "@nx/detox:test", + "options": { + "detoxConfiguration": "android.emu.local", + "buildTarget": "mobile-e2e:build-android" + }, + "configurations": { + "bare": { + "detoxConfiguration": "android.emu.debug", + "buildTarget": "mobile-e2e:build-android:bare" + }, + "production": { + "detoxConfiguration": "android.emu.release", + "buildTarget": "mobile-e2e:build-android:production" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + } + }, + "tags": [], + "implicitDependencies": ["mobile"] +} diff --git a/apps/mobile-e2e/src/app.spec.ts b/apps/mobile-e2e/src/app.spec.ts new file mode 100644 index 0000000..826c003 --- /dev/null +++ b/apps/mobile-e2e/src/app.spec.ts @@ -0,0 +1,11 @@ +import { device, element, by, expect } from 'detox'; + +describe('movieweb', () => { + beforeEach(async () => { + await device.reloadReactNative(); + }); + + it('should display welcome message', async () => { + await expect(element(by.id('heading'))).toHaveText('Welcome movie-web 👋'); + }); +}); diff --git a/apps/mobile-e2e/test-setup.ts b/apps/mobile-e2e/test-setup.ts new file mode 100644 index 0000000..a4e12aa --- /dev/null +++ b/apps/mobile-e2e/test-setup.ts @@ -0,0 +1,5 @@ +import { device } from 'detox'; + +beforeAll(async () => { + await device.launchApp(); +}); diff --git a/apps/mobile-e2e/tsconfig.e2e.json b/apps/mobile-e2e/tsconfig.e2e.json new file mode 100644 index 0000000..a7ccc6e --- /dev/null +++ b/apps/mobile-e2e/tsconfig.e2e.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "sourceMap": false, + "outDir": "../../dist/out-tsc", + "allowJs": true, + "types": ["node", "jest", "detox"] + }, + "include": ["src/**/*.ts", "src/**/*.js"] +} diff --git a/apps/mobile-e2e/tsconfig.json b/apps/mobile-e2e/tsconfig.json new file mode 100644 index 0000000..08841a7 --- /dev/null +++ b/apps/mobile-e2e/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.e2e.json" + } + ] +} diff --git a/apps/mobile/.eslintrc.js b/apps/mobile/.eslintrc.js new file mode 100644 index 0000000..e3da589 --- /dev/null +++ b/apps/mobile/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + extends: ['../../.eslintrc.js'], + ignorePatterns: ['/*.js', '/*.d.ts'], + overrides: [ + { + files: ['*.ts', '*.tsx', '*.js', '*.jsx'], + rules: {}, + }, + { + files: ['*.ts', '*.tsx'], + rules: {}, + }, + { + files: ['*.js', '*.jsx'], + rules: {}, + }, + ], + rules: { + 'react/jsx-uses-react': 'off', + 'react/react-in-jsx-scope': 'off', + 'react/require-default-props': 'off', + 'react/destructuring-assignment': 'off', + 'react/jsx-filename-extension': [ + 'error', + { extensions: ['.js', '.tsx', '.jsx'] }, + ], + 'react/jsx-props-no-spreading': 'off', + 'react/no-unstable-nested-components': 'off', + 'no-use-before-define': 'off', + }, +}; diff --git a/apps/mobile/.eslintrc.json b/apps/mobile/.eslintrc.json new file mode 100644 index 0000000..d3e61a2 --- /dev/null +++ b/apps/mobile/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.js"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/mobile/.gitignore b/apps/mobile/.gitignore new file mode 100644 index 0000000..51a7595 --- /dev/null +++ b/apps/mobile/.gitignore @@ -0,0 +1,44 @@ +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ +android/ +ios/ + +# Native +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo + + +# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb +# The following patterns were generated by expo-cli + +expo-env.d.ts +# @end expo-cli \ No newline at end of file diff --git a/apps/mobile/README.md b/apps/mobile/README.md deleted file mode 100644 index 36b29e6..0000000 --- a/apps/mobile/README.md +++ /dev/null @@ -1 +0,0 @@ -This will be the folder the mobile native app. diff --git a/apps/mobile/app.json b/apps/mobile/app.json new file mode 100644 index 0000000..74f4d26 --- /dev/null +++ b/apps/mobile/app.json @@ -0,0 +1,53 @@ +{ + "expo": { + "name": "movie-web", + "slug": "mw-mobile", + "version": "1.0.0", + "orientation": "portrait", + "scheme":"dev.movieweb.app", + "icon": "./assets/images/icon.png", + "splash": { + "image": "./assets/images/splash.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "jsEngine": "jsc", + "updates": { + "fallbackToCacheTimeout": 0 + }, + "assetBundlePatterns": [ + "**/*" + ], + "ios": { + "supportsTablet": true, + "bundleIdentifier": "dev.movieweb.app" + }, + "android": { + "adaptiveIcon": { + "foregroundImage": "./assets/images/adaptive-icon.png", + "backgroundColor": "#FFFFFF" + }, + "package": "dev.movieweb.app" + }, + "web": { + "favicon": "./assets/images/favicon.png", + "bundler": "metro" + }, + "plugins": [ + "expo-router", + [ + "@config-plugins/detox", + { + "skipProguard": false, + "subdomains": [ + "10.0.2.2", + "localhost" + ] + } + ] + ], + "experiments": { + "typedRoutes": true + } + } +} diff --git a/apps/mobile/app/(tabs)/_layout.tsx b/apps/mobile/app/(tabs)/_layout.tsx new file mode 100644 index 0000000..1d235a1 --- /dev/null +++ b/apps/mobile/app/(tabs)/_layout.tsx @@ -0,0 +1,56 @@ +import FontAwesome from '@expo/vector-icons/FontAwesome'; +import { Link, Tabs } from 'expo-router'; +import { Pressable, useColorScheme } from 'react-native'; + +import Colors from '../../constants/Colors'; + +/** + * You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/ + */ +function TabBarIcon(props: { + name: React.ComponentProps['name']; + color: string; +}) { + return ; +} + +export default function TabLayout() { + const colorScheme = useColorScheme(); + + return ( + + , + headerRight: () => ( + + + {({ pressed }) => ( + + )} + + + ), + }} + /> + , + }} + /> + + ); +} diff --git a/apps/mobile/app/(tabs)/index.tsx b/apps/mobile/app/(tabs)/index.tsx new file mode 100644 index 0000000..3a5bb5f --- /dev/null +++ b/apps/mobile/app/(tabs)/index.tsx @@ -0,0 +1,35 @@ +import { StyleSheet } from 'react-native'; + +import EditScreenInfo from '../../components/EditScreenInfo'; +import { Text, View } from '../../components/Themed'; + +export default function TabOneScreen() { + return ( + + Tab One + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + title: { + fontSize: 20, + fontWeight: 'bold', + }, + separator: { + marginVertical: 30, + height: 1, + width: '80%', + }, +}); diff --git a/apps/mobile/app/(tabs)/two.tsx b/apps/mobile/app/(tabs)/two.tsx new file mode 100644 index 0000000..cc6a377 --- /dev/null +++ b/apps/mobile/app/(tabs)/two.tsx @@ -0,0 +1,35 @@ +import { StyleSheet } from 'react-native'; + +import EditScreenInfo from '../../components/EditScreenInfo'; +import { Text, View } from '../../components/Themed'; + +export default function TabTwoScreen() { + return ( + + Tab Two + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + title: { + fontSize: 20, + fontWeight: 'bold', + }, + separator: { + marginVertical: 30, + height: 1, + width: '80%', + }, +}); diff --git a/apps/mobile/app/+html.tsx b/apps/mobile/app/+html.tsx new file mode 100644 index 0000000..2fe2848 --- /dev/null +++ b/apps/mobile/app/+html.tsx @@ -0,0 +1,46 @@ +import { ScrollViewStyleReset } from 'expo-router/html'; + +// This file is web-only and used to configure the root HTML for every +// web page during static rendering. +// The contents of this function only run in Node.js environments and +// do not have access to the DOM or browser APIs. +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + + + + + {/* + This viewport disables scaling which makes the mobile website act more like a native app. + However this does reduce built-in accessibility. If you want to enable scaling, use this instead: + + */} + + {/* + Disable body scrolling on web. This makes ScrollView components work closer to how they do on native. + However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line. + */} + + + {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */} +