这是indexloc提供的服务,不要输入任何密码
Skip to content

Non-trivial changed #2951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 59 additions & 45 deletions boilerplate/README.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,91 @@
# Welcome to your new ignited app!
# Welcome to the Spacebox Application!

> The latest and greatest boilerplate for Infinite Red opinions
## Overview

This is the boilerplate that [Infinite Red](https://infinite.red) uses as a way to test bleeding-edge changes to our React Native stack.
The Spacebox application is a mobile application that allows users to manage their items. It involves two screens:

- [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)
- The Login screen, where users can log in to their account.
- The Home screen, where users can view their items, add new items, and remove items.

## Getting Started
Optionally, it involves a backend application that allows users to manage their items using a REST API. The backend application is built using Node.js and Express, and it uses PostgreSQL as the database. The backend application is exposed to the internet using ngrok, which allows users to access it from anywhere. The backend application can be disabled through the configuration file in app/config.

For ease of use, the user id is hardcoded in the application and the application doesn't implement any authentication mechanism (e.g JWT, OAuth, etc.).

The mobile application is built using React Native and Expo and has been tested **on iOS only.**

The application is translated into English and Traditional Chinese. The language is set based on the device's language settings. If the device's language is not supported, the application will default to English.

## Setup the application

Make sure you run the Node.js version 22.0 or higher.
You can check your Node.js version by running the following command:

```bash
yarn
yarn start
node -v
```

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:
If you don't have Node.js installed, you can download it from the official website: [Node.js](https://nodejs.org/)
If you have Node.js installed, you can run the following command to install the dependencies:

```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
npm install
```

### `./assets` directory
### Setup the backend application

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`:
In order to run the backend application in the folder `backend-app-spacebox`, you need to have the following dependencies installed:

```tree
assets
├── icons
└── images
```
- Docker compose
- Node.js

**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.
Once you have the dependencies installed, you can run the following command to start the backend application:

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.
```bash
docker-compose up -d
```

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).
The backend application will be running on port 3002 locally and the database will be running on port 5432 locally.
An ngrok server is configured to expose the backend application to the internet. To grab the ngrok URL, you can open your browser and go to the following URL: http://localhost:4040/inspect/http

How to use your `icon` or `image` assets:
### Setup the react-native expo application

```typescript
import { Image } from 'react-native';
Once the backend application is running, you can run the following command to start the react-native expo application in the root folder of the project:

const MyComponent = () => {
return (
<Image source={require('../assets/images/my_image.png')} />
);
};
```bash
npm install
```

## Running Maestro end-to-end tests
Set the backend configuration url in app/config if you wanna use the backend API previously started.

Follow our [Maestro Setup](https://ignitecookbook.com/docs/recipes/MaestroSetup) recipe.
```bash
`API_URL` should be set to the ngrok URL you got from the previous step.
`USE_API_ITEMS` should be set to `true` to use the backend API.
```

## Next Steps
To run the application on the IOS simulator, you can run the following command:

### Ignite Cookbook
```bash
npm run ios
```

[Ignite Cookbook](https://ignitecookbook.com/) is an easy way for developers to browse and share code snippets (or “recipes”) that actually work.
If you just want to run the current development build without changing the native code, you can run the following command:

```bash
npm run start:ios
```

### Upgrade Ignite boilerplate
## Run Tests

Read our [Upgrade Guide](https://ignitecookbook.com/docs/recipes/UpdatingIgnite) to learn how to upgrade your Ignite project.
To run the tests, you can run the following command:

## Community
```bash
npm test
```

⭐️ 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).
To run the tests in watch mode, you can run the following command:

💬 Join us on [Slack](https://join.slack.com/t/infiniteredcommunity/shared_invite/zt-1f137np4h-zPTq_CbaRFUOR_glUFs2UA) to discuss.
```bash
npm test:watch
```

📰 Make our Editor-in-chief happy by [reading the React Native Newsletter](https://reactnativenewsletter.com/).
Note: The tests should be run with the config `USE_API_ITEMS` set to `false` in order to run the tests without the backend API.
52 changes: 23 additions & 29 deletions boilerplate/app.json
Original file line number Diff line number Diff line change
@@ -1,58 +1,52 @@
{
"name": "HelloWorld",
"displayName": "HelloWorld",
"name": "Spacebox",
"displayName": "Spacebox",
"expo": {
"name": "HelloWorld",
"slug": "HelloWorld",
"scheme": "helloworld",
"name": "Spacebox",
"slug": "Spacebox",
"scheme": "spacebox",
"version": "1.0.0",
"orientation": "portrait",
"backgroundColor": "#000000",
"userInterfaceStyle": "automatic",
"icon": "./assets/images/app-icon-all.png",
"updates": {
"fallbackToCacheTimeout": 0
},
"newArchEnabled": false,
"newArchEnabled": true,
"jsEngine": "hermes",
"assetBundlePatterns": [
"**/*"
],
"android": {
"icon": "./assets/images/app-icon-android-legacy.png",
"package": "com.helloworld",
"adaptiveIcon": {
"foregroundImage": "./assets/images/app-icon-android-adaptive-foreground.png",
"backgroundImage": "./assets/images/app-icon-android-adaptive-background.png"
},
"allowBackup": false
},
"assetBundlePatterns": ["**/*"],
"ios": {
"icon": "./assets/images/app-icon-ios.png",
"icon": "./assets/images/app-icon-all.png",
"supportsTablet": true,
"bundleIdentifier": "com.helloworld"
},
"web": {
"favicon": "./assets/images/app-icon-web-favicon.png",
"bundler": "metro"
"bundleIdentifier": "com.spacebox",
"infoPlist": {
"ITSAppUsesNonExemptEncryption": false
}
},
"plugins": [
"expo-localization",
"expo-font",
[
"expo-splash-screen",
{
"image": "./assets/images/app-icon-android-adaptive-foreground.png",
"image": "./assets/images/spacebox.png",
"imageWidth": 300,
"resizeMode": "contain",
"backgroundColor": "#191015"
"backgroundColor": "#FFFFFF"
}
]
],
"experiments": {
"tsconfigPaths": true
},
"extra": {
"eas": {
"projectId": "b98c7724-a87f-4475-a75d-d70bc3755e47"
}
},
"android": {
"package": "com.spacebox"
}
},
"ignite": {
"version": "UNKNOWN"
}
}
91 changes: 38 additions & 53 deletions boilerplate/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,42 @@ 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")
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 { useInitialRootStore } from "./models" // @mst remove-current-line
import { AppNavigator, useNavigationPersistence } 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"
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 { useInitialRootStore } from './models';
import { AppNavigator, useNavigationPersistence } 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';
import './utils/gestureHandler';
import { initI18n } from './i18n';
import './utils/ignoreWarnings';

export const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE';

// Web linking configuration
const prefix = Linking.createURL("/")
const prefix = Linking.createURL('/');
const config = {
screens: {
Login: {
path: "",
},
Welcome: "welcome",
Demo: {
screens: {
DemoShowroom: {
path: "showroom/:queryIndex?/:itemIndex?",
},
DemoDebug: "debug",
DemoPodcastList: "podcast",
DemoCommunity: "community",
},
path: '',
},
Home: 'home',
},
}
};

/**
* This is the root component of our app.
Expand All @@ -66,48 +61,38 @@ export function App() {
initialNavigationState,
onNavigationStateChange,
isRestored: isNavigationStateRestored,
} = useNavigationPersistence(storage, NAVIGATION_PERSISTENCE_KEY)
} = useNavigationPersistence(storage, NAVIGATION_PERSISTENCE_KEY);

const [areFontsLoaded, fontLoadError] = useFonts(customFontsToLoad)
const [isI18nInitialized, setIsI18nInitialized] = useState(false)
const [areFontsLoaded, fontLoadError] = useFonts(customFontsToLoad);
const [isI18nInitialized, setIsI18nInitialized] = useState(false);

useEffect(() => {
initI18n()
.then(() => setIsI18nInitialized(true))
.then(() => loadDateFnsLocale())
}, [])
.then(() => loadDateFnsLocale());
}, []);

// @mst replace-next-line useEffect(() => {
const { rehydrated } = useInitialRootStore(() => {
// @mst replace-next-line
// This runs after the root store has been initialized and rehydrated.

// 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)

// @mst replace-next-line }, [])
})
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 (
!rehydrated || // @mst remove-current-line
!rehydrated ||
!isNavigationStateRestored ||
!isI18nInitialized ||
(!areFontsLoaded && !fontLoadError)
) {
return null
return null;
}

const linking = {
prefixes: [prefix],
config,
}
};

// otherwise, we're ready to render the app
return (
Expand All @@ -122,5 +107,5 @@ export function App() {
</KeyboardProvider>
</ErrorBoundary>
</SafeAreaProvider>
)
);
}
24 changes: 24 additions & 0 deletions boilerplate/app/client/client.gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This file is auto-generated by @hey-api/openapi-ts

import type { ClientOptions } from './types.gen';
import {
type Config,
type ClientOptions as DefaultClientOptions,
createClient,
createConfig,
} from '@hey-api/client-fetch';

/**
* The `createClientConfig()` function will be called on client initialization
* and the returned object will become the client's initial configuration.
*
* You may want to initialize your client this way instead of calling
* `setConfig()`. This is useful for example if you're using Next.js
* to ensure your client always has the correct values.
*/
export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> =
(
override?: Config<DefaultClientOptions & T>,
) => Config<Required<DefaultClientOptions> & T>;

export const client = createClient(createConfig<ClientOptions>());
3 changes: 3 additions & 0 deletions boilerplate/app/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This file is auto-generated by @hey-api/openapi-ts
export * from './types.gen';
export * from './sdk.gen';
Loading