Skip to content

Commit

Permalink
Merge branch 'main' into @Filip131311/AddAndroidLocalization
Browse files Browse the repository at this point in the history
  • Loading branch information
filip131311 committed Oct 23, 2024
2 parents 4cced63 + 91a127d commit f080b13
Show file tree
Hide file tree
Showing 166 changed files with 36,191 additions and 21,876 deletions.
File renamed without changes.
43 changes: 43 additions & 0 deletions packages/docs/docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,46 @@ src="/img/docs/restart_extension.png"/>

For main extension code, you can set breakpoints in vscode and use debugger normally, logs will appear in the Debug Console panel.
Unfortunately debugging isn't available for the frontend code, however you can use vscode's builtin chrome devtools to see logs or interact with the frontend portion of the project – for this you'll need to run command "Developer: Open Webview Developer Tools" from the command palette in the Extension Host window.

## Shared app template

We provide few shared components with common code across tests apps in `shared/`
directory.
They only depend on `react-native`. Components in `shared/navigation` additionally
depend on `expo-router` and `expo-icons`.

To use them in the app:
1. Add npm command in test app package.json
- for expo-router apps: `"copy-shared": "../shared/copy.sh expo-router ./shared"`.
- for RN apps: `"copy-shared": "../shared/copy.sh bare ./shared"`.
2. Run it: `npm run copy-shared`. This copies shared components to `./shared`.
3. For RN apps, replace `App.tsx` with the `./shared/MainScreen.tsx` component.
```ts
import {MainScreen} from './shared/MainScreen';

export default MainScreen;
```
4. For apps with expo router, replace `app/(tabs)/_layout.tsx` and
`app/(tabs)/index.tsx` files.
```ts
// contents of `app/(tabs)/_layout.ts`
import { TabLayout } from "@/shared/navigation/TabLayout";
export default TabLayout;
```

```ts
// contents of `app/(tabs)/index.ts`
import { MainScreen } from "@/shared/MainScreen";
export default MainScreen;
```

You can also use other components in `shared` (e.g. `Text`, `Button`,
`useScheme`) to theme the app.

After updating shared components you need to copy them again by running
`npm run copy-shared` in every test app.

`shared/copy.sh bare|expo-router DEST` script works by copying shared directory to `DEST`
and removing `navigation` directory if `bare` argument is used.
28 changes: 20 additions & 8 deletions packages/docs/docs/launch-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,23 @@ Below is an example of how the `launch.json` file could look like with android v
Instead of letting Radon IDE build your app, you can use scripts (`buildScript` option) or [Expo
Application Services (EAS)](https://expo.dev/eas) (`eas` option) to do it.

The requirement for scripts is to output the absolute path to the built app as the
last line of the standard output.

Both `buildScript` and `eas` are objects having `ios` and `android` optional
The requirement for scripts is to output the absolute path to the built app as
the last line of the standard output. If custom fingerprint script is used, it
should output fingerprint (a string identifying the build) as the last line of the standard output. When
fingerprint changes between invocations, RN IDE will rebuild the project. The
IDE runs fingerprint quite frequently (i.e., on every file save), so this
process should be fast and avoid over the network communication.

Both `customBuild` and `eas` are objects having `ios` and `android` optional
keys. You can't specify one platform in both custom script and EAS build
options.

`buildScript.ios` and `buildScript.android` are string keys, representing custom
command used to build the app. Example below:
`customBuild.ios` and `customBuild.android` have following structure with
optional keys that can be used independently:
- `buildCommand` – string, specifies a command used for building.
- `fingerprintCommand` – string, specifies a command used for creating fingerprint.

Example:
```json
{
"version": "0.2.0",
Expand All @@ -146,8 +154,12 @@ command used to build the app. Example below:
"type": "radon-ide",
"request": "launch",
"name": "Radon IDE panel",
"buildScript": {
"android": "npm run build:ftp-fetch-android"
"customBuild": {
"android": { "buildCommand": "npm run build:ftp-fetch-android" }
"ios": {
"buildCommand": "npm run build:ftp-fetch-ios",
"fingerprintCommand": "date '+%Y-%m-%d'"
}
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion packages/simulator-server
Binary file modified packages/vscode-extension/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 20 additions & 8 deletions packages/vscode-extension/lib/metro_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,19 @@ function adaptMetroConfig(config) {
}
} else if (module.path === "__env__") {
// this handles @expo/env plugin, which is used to inject environment variables
// the code below instantiates a global variable __EXPO_ENV_PRELUDE_LINES__ that stores
// the number of lines in the prelude. This is used to calculate the line number offset
// when reporting line numbers from the JS runtime. The reason why this is needed, is that
// the code below exposes the number of lines in the prelude.
// This is used to calculate the line number offset
// when reporting line numbers from the JS runtime, breakpoints
// and uncaught exceptions. The reason why this is needed, is that
// metro doesn't include __env__ prelude in the source map resulting in the source map
// transformation getting shifted by the number of lines in the prelude.
const expoEnvCode = module.output[0].data.code;
if (!expoEnvCode.includes("__EXPO_ENV_PRELUDE_LINES__")) {
module.output[0].data.code = `${expoEnvCode};var __EXPO_ENV_PRELUDE_LINES__=${module.output[0].data.lineCount};`;
}
// transformation getting shifted by the number of lines in the expo generated prelude.
process.stdout.write(
JSON.stringify({
type: "RNIDE_expo_env_prelude_lines",
lineCount: module.output[0].data.lineCount,
})
);
process.stdout.write("\n");
}
return origProcessModuleFilter(module);
};
Expand Down Expand Up @@ -133,6 +137,14 @@ function adaptMetroConfig(config) {
const ReporterImpl = require("./metro_reporter");
config.reporter = new ReporterImpl();

process.stdout.write(
JSON.stringify({
type: "RNIDE_watch_folders",
watchFolders: [config.projectRoot, ...config.watchFolders], // metro internally adds projectRoot as first entry to watch folders
})
);
process.stdout.write("\n");

return config;
}

Expand Down
23 changes: 20 additions & 3 deletions packages/vscode-extension/lib/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ global.__RNIDE_onDebuggerConnected = function () {
global.__fbDisableExceptionsManager = true;
};

// We add log this trace to diagnose issues with loading runtime in the IDE
// It is necessary that this call is before we override console methods, otherwise
// this message would be visible in the debug console panel for the IDE users.
console.log("__RNIDE_INTERNAL: react-native-ide runtime loaded");

function wrapConsole(consoleFunc) {
return function (...args) {
const stack = parseErrorStack(new Error().stack);
const expoLogIndex = stack.findIndex((frame) => frame.methodName === "__expoConsoleLog");
const location = expoLogIndex > 0 ? stack[expoLogIndex + 1] : stack[1];
const lineOffset = global.__EXPO_ENV_PRELUDE_LINES__ || 0;
args.push(location.file, location.lineNumber - lineOffset, location.column);
args.push(location.file, location.lineNumber, location.column);
return consoleFunc.apply(console, args);
};
}
Expand All @@ -43,5 +47,18 @@ global.__RNIDE_register_navigation_plugin = function (name, plugin) {
};

AppRegistry.setWrapperComponentProvider((appParameters) => {
return require("__RNIDE_lib__/wrapper.js").PreviewAppWrapper;
return require("__RNIDE_lib__/wrapper.js").AppWrapper;
});

// Some apps may use AppRegistry.setWrapperComponentProvider to provide a custom wrapper component.
// Apparenlty, this method only supports one provided per app. In order for this to work, we
// overwrite the method to wrap the custom wrapper component with the app wrapper that IDE uses
// from the wrapper.js file.
const origSetWrapperComponentProvider = AppRegistry.setWrapperComponentProvider;
AppRegistry.setWrapperComponentProvider = (provider) => {
console.info("RNIDE: The app is using a custom wrapper component provider");
origSetWrapperComponentProvider((appParameters) => {
const CustomWrapper = provider(appParameters);
return require("__RNIDE_lib__/wrapper.js").createNestedAppWrapper(CustomWrapper);
});
};
23 changes: 13 additions & 10 deletions packages/vscode-extension/lib/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ const RNInternals = {
} catch (e) {}
throw new Error("Couldn't locate LoadingView module");
},
get DevMenu() {
return require("react-native/Libraries/NativeModules/specs/NativeDevMenu").default;
},
};

function getCurrentScene() {
Expand All @@ -70,7 +67,7 @@ function useAgentListener(agent, eventName, listener, deps = []) {
}, [agent, ...deps]);
}

export function PreviewAppWrapper({ children, initialProps, ..._rest }) {
export function AppWrapper({ children, initialProps, ..._rest }) {
const rootTag = useContext(RootTagContext);
const [devtoolsAgent, setDevtoolsAgent] = useState(null);
const [hasLayout, setHasLayout] = useState(false);
Expand Down Expand Up @@ -246,12 +243,6 @@ export function PreviewAppWrapper({ children, initialProps, ..._rest }) {
[mainContainerRef]
);

useAgentListener(devtoolsAgent, "RNIDE_iosDevMenu", (_payload) => {
// this native module is present only on iOS and will crash if called
// on Android
RNInternals.DevMenu.show();
});

useAgentListener(
devtoolsAgent,
"RNIDE_showStorybookStory",
Expand Down Expand Up @@ -309,3 +300,15 @@ export function PreviewAppWrapper({ children, initialProps, ..._rest }) {
</View>
);
}

export function createNestedAppWrapper(InnerWrapperComponent) {
function WrapperComponent(props) {
const { children, ...rest } = props;
return (
<AppWrapper {...rest}>
<InnerWrapperComponent {...rest}>{children}</InnerWrapperComponent>
</AppWrapper>
);
}
return WrapperComponent;
}
5 changes: 2 additions & 3 deletions packages/vscode-extension/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 29 additions & 10 deletions packages/vscode-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
"workspaceContains:app.config.js",
"workspaceContains:app.config.ts"
],
"version": "0.0.19",
"version": "0.0.21",
"engines": {
"vscode": "^1.75.0",
"os": "darwin"
"vscode": "^1.75.0"
},
"extensionKind": [
"workspace"
Expand Down Expand Up @@ -208,17 +207,37 @@
"type": "string",
"description": "Location of Metro config relative to the workspace. This is used for using custom configs for e.g. development."
},
"buildScript": {
"customBuild": {
"type": "object",
"description": "Scripts used to build Android or iOS app or fetch them from known location. Executed as a part of building process. Should print a JSON result from `eas build` command or a filesystem path to the built app as the last line of the standard output.\nIf using EAS, it should be invoked with --json --non-interactive flags and use a profile for development, iOS additionally needs `\"ios.simulator\": true` config option in eas.json",
"description": "Configuration for using custom scripts for building and fingerprinting the app.",
"properties": {
"ios": {
"type": "string",
"description": "Script used to build iOS app."
"type": "object",
"description": "Configuration for iOS.",
"properties": {
"buildCommand": {
"type": "string",
"description": "Script used to build the app. It should build the app in debug mode and print path to the built app as a last line of its standard output."
},
"fingerprintCommand": {
"type": "string",
"description": "Script used to fingerprint the app. It should print workspace hash as a last line of its standard output."
}
}
},
"android": {
"type": "string",
"description": "Script used to build Android app."
"type": "object",
"description": "Configuration for Android.",
"properties": {
"buildCommand": {
"type": "string",
"description": "Script used to build the app. It should build the app in debug mode and print path to the built app as a last line of its standard output."
},
"fingerprintCommand": {
"type": "string",
"description": "Script used to fingerprint the app. It should print workspace hash as a last line of its standard output."
}
}
}
}
},
Expand Down Expand Up @@ -414,7 +433,7 @@
"build:expo-fingerprint": "esbuild ./node_modules/@expo/fingerprint/build/sourcer/ExpoConfigLoader.js --bundle --format=cjs --outfile=dist/ExpoConfigLoader.js --platform=node --minify",
"build:webview": "vite build --mode production && cp ./node_modules/@vscode/codicons/dist/codicon.* dist/.",
"build:sim-server-debug": "bash ./scripts/build-sim-server.sh dist Debug",
"build:sim-server": "bash ./scripts/build-sim-server.sh dist Release",
"build:sim-server": "bash ./scripts/install-sim-server-release-build.sh dist",
"build:debug": "npm run build:extension-debug && npm run build:sim-server-debug",
"build:dist": "npm run build:extension && npm run build:sim-server && npm run build:webview",
"watch:extension": "vite",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

# This script uses the GitHub CLI to download pre-built signed release versions
# of the simulator-server binaries and places them in the build location for packaging.
# In order to use this script you need to have GitHub CLI installed and authenticated
# with the access to the simulator-server repo.

set -e

# execute this from the vscode-extension package directory
cd "$(dirname "$0")/.."

# take output directory from first argument or default to out - relative to the vscode-extension package location
output_dir="${1:-out}"

submodule_status=$(git submodule status ../simulator-server)
if [[ $submodule_status == -* ]]; then # submodule is not initialized
echo "Submodule is not initialized"
exit 1
fi

# For release builds we always make sure that submodule is up to date
git submodule update --init -- ../simulator-server

submodule_status=$(git submodule status ../simulator-server)
if [[ $submodule_status == +* ]]; then # submodule is not up-to-date
echo "Submodule is not up to date"
exit 1
fi

# Create the target directory if it doesn't exist
mkdir -p "$output_dir"

# Get tag of simulator-server submodule
sim_server_tag=$(git -C ../simulator-server describe --tags)

echo "Downloading sim-server binaries for tag $sim_server_tag"

# Download Mac and Windows binaries using gh CLI and place them in the correcto location
mac_binary_path="$output_dir/sim-server"
gh release download $sim_server_tag -R software-mansion-labs/simulator-server -p simulator-server -O "$mac_binary_path"
chmod +x "$mac_binary_path"

win_binary_path="$output_dir/sim-server-executable.exe"
gh release download $sim_server_tag -R software-mansion-labs/simulator-server -p simulator-server.exe -O "$win_binary_path"
chmod +x "$win_binary_path"
7 changes: 6 additions & 1 deletion packages/vscode-extension/src/Logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ const logger = {
},

error(message: string, ...args: any[]) {
outputChannel.error(message, ...args);
if (args.length > 0 && args[args.length - 1] instanceof Error) {
const error = args[args.length - 1] as Error;
outputChannel.error(error, message, ...args.slice(0, -1));
} else {
outputChannel.error(message, ...args);
}
},

openOutputPanel() {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export class BuildAndroidProgressProcessor implements BuildProgressProcessor {
if (!this.tasksToComplete) {
return;
}
this.progressListener(Math.min(1, this.completedTasks / this.tasksToComplete));
// the 0.999 max value is here to prevent situations in which users see 100% indiction,
// but the build process is still takeing a couple more seconds.
this.progressListener(Math.min(0.999, this.completedTasks / this.tasksToComplete));
}

processLine(line: string): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ export class BuildIOSProgressProcessor implements BuildProgressProcessor {
if (!this.tasksToComplete) {
return;
}
this.progressListener(Math.min(1, this.completedTasks / this.tasksToComplete));
// the 0.999 max value is here to prevent situations in which users see 100% indiction,
// but the build process is still takeing a couple more seconds.
this.progressListener(Math.min(0.999, this.completedTasks / this.tasksToComplete));
}

async processLine(line: string) {
Expand Down
Loading

0 comments on commit f080b13

Please sign in to comment.