Skip to content
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

[menu-bar][cli] Extract device types in a common file #66

Merged
merged 2 commits into from
Sep 20, 2023
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

- Add check for missing changelogs. ([#49](https://github.com/expo/orbit/pull/49) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Clean up eas-shared package. ([#60](https://github.com/expo/orbit/pull/60) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Unify device types across menu-bar, cli and eas-shared package. ([#66](https://github.com/expo/orbit/pull/66) by [@gabrieldonadel](https://github.com/gabrieldonadel))

## 0.1.2 — 2023-08-13

Expand Down
5 changes: 3 additions & 2 deletions apps/cli/src/commands/BootDevice.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AndroidEmulator, IosSimulator } from "common-types/devices";
import { Emulator, Simulator } from "eas-shared";
import { getRunningDevicesAsync } from "eas-shared/build/run/android/adb";

Expand All @@ -16,7 +17,7 @@ export async function bootDeviceAsync({
try {
await Simulator.ensureSimulatorBootedAsync({
udid: id,
} as Simulator.IosSimulator);
} as IosSimulator);
} catch (error) {
if (
error instanceof Error &&
Expand All @@ -39,7 +40,7 @@ export async function bootDeviceAsync({
await Emulator.bootEmulatorAsync(
{
name: id,
} as Emulator.AndroidDevice,
} as AndroidEmulator,
{ noAudio }
);
}
26 changes: 13 additions & 13 deletions apps/cli/src/commands/ListDevices.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { AppleDevice, Emulator, Simulator } from "eas-shared";
import { Platform } from "../utils";
import {
IosSimulator,
AppleConnectedDevice,
AppleDevice,
Emulator,
Simulator,
} from "eas-shared";
import { Platform } from "../utils";
AndroidConnectedDevice,
AndroidEmulator,
} from "common-types/devices";

type Device<P> = P extends Platform.Ios
? Simulator.IosSimulator
? IosSimulator | AppleConnectedDevice
: P extends Platform.Android
? Emulator.AndroidDevice
: Simulator.IosSimulator | Emulator.AndroidDevice;
? AndroidConnectedDevice | AndroidEmulator
: never;

export async function listDevicesAsync<P extends Platform>({
platform,
}: {
platform: P;
}): Promise<Device<P>[]> {
let availableAndroidDevices: Emulator.AndroidDevice[] = [];
let availableIosDevices: Array<
Simulator.IosSimulator | AppleConnectedDevice
> = [];
let availableAndroidDevices: (AndroidConnectedDevice | AndroidEmulator)[] =
[];
let availableIosDevices: Array<IosSimulator | AppleConnectedDevice> = [];

if (platform === "ios" || platform === "all") {
try {
availableIosDevices = availableIosDevices.concat(
await Simulator.getAvaliableIosSimulatorsListAsync()
await Simulator.getAvailableIosSimulatorsListAsync()
);

const connectedDevices = await AppleDevice.getConnectedDevicesAsync();
Expand Down
6 changes: 5 additions & 1 deletion apps/cli/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
"compilerOptions": {
"outDir": "build",
"rootDir": "src",
"paths": {
"common-types/*": ["../../common-types/src/*"]
}
},
"include": ["src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
"exclude": ["**/__mocks__/*", "**/__tests__/*"],
"references": [{ "path": "../../common-types/tsconfig.json" }]
}
3 changes: 2 additions & 1 deletion apps/menu-bar/src/commands/listDevicesAsync.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Device } from 'common-types/devices';

import MenuBarModule from '../modules/MenuBarModule';
import { Device } from '../utils/device';

type ListDevicesAsyncOptions = {
platform: 'android' | 'ios' | 'all';
Expand Down
52 changes: 26 additions & 26 deletions apps/menu-bar/src/components/DeviceItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { palette } from '@expo/styleguide-native';
import { Device } from 'common-types/devices';
import { useState } from 'react';
import { StyleSheet, Pressable, PlatformColor } from 'react-native';

Expand All @@ -9,7 +10,7 @@ import CableConnectorIcon from '../assets/icons/cable-connector.svg';
import IphoneIcon from '../assets/icons/iphone.svg';
import WifiIcon from '../assets/icons/wifi.svg';
import { useTheme } from '../providers/ThemeProvider';
import { Device } from '../utils/device';
import { isVirtualDevice } from '../utils/device';
import { capitalize } from '../utils/helpers';
import { useExpoTheme } from '../utils/useExpoTheme';

Expand All @@ -28,6 +29,8 @@ const DeviceItem = ({ device, onPress, onPressLaunch, selected }: Props) => {
const [isHovered, setIsHovered] = useState(false);
const [isDeviceLaunching, setDeviceLaunching] = useState(false);

const isVirtual = isVirtualDevice(device);

return (
<Pressable
style={[
Expand Down Expand Up @@ -71,11 +74,11 @@ const DeviceItem = ({ device, onPress, onPressLaunch, selected }: Props) => {
<Text numberOfLines={1}>{device.name}</Text>
<Text style={styles.description} color="secondary" leading="small">
{capitalize(device.deviceType)}
{device.osVersion && ` · ${device.osVersion}`}
{'osVersion' in device && ` · ${device.osVersion}`}
</Text>
</View>
</Row>
{device.deviceType === 'device' && (
{!isVirtual && (
<>
{device.connectionType === 'Network' ? (
<WifiIcon height={20} width={20} fill={PlatformColor('text')} />
Expand All @@ -84,7 +87,7 @@ const DeviceItem = ({ device, onPress, onPressLaunch, selected }: Props) => {
)}
</>
)}
{device.deviceType !== 'device' && device.state === 'Booted' && (
{isVirtual && device.state === 'Booted' && (
<>
<Text color="success" style={styles.indicator}>
Expand All @@ -95,32 +98,29 @@ const DeviceItem = ({ device, onPress, onPressLaunch, selected }: Props) => {
</Text>
</>
)}
{device.deviceType !== 'device' && device.state === 'Shutdown' && isDeviceLaunching && (
{isVirtual && device.state === 'Shutdown' && isDeviceLaunching && (
<Text color="secondary" style={styles.indicator}>
Launching…
</Text>
)}
{isHovered &&
device.deviceType !== 'device' &&
device.state === 'Shutdown' &&
!isDeviceLaunching && (
<Button
title="Launch"
disabled={isDeviceLaunching}
color="primary"
onPress={async () => {
setDeviceLaunching(true);
try {
await onPressLaunch();
} catch (error) {
console.warn(error);
} finally {
setDeviceLaunching(false);
}
}}
style={styles.button}
/>
)}
{isHovered && isVirtual && device.state === 'Shutdown' && !isDeviceLaunching && (
<Button
title="Launch"
disabled={isDeviceLaunching}
color="primary"
onPress={async () => {
setDeviceLaunching(true);
try {
await onPressLaunch();
} catch (error) {
console.warn(error);
} finally {
setDeviceLaunching(false);
}
}}
style={styles.button}
/>
)}
</Row>
</Pressable>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/menu-bar/src/hooks/useListDevices.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Device } from 'common-types/devices';
import { useCallback, useEffect, useState } from 'react';
import { DeviceEventEmitter } from 'react-native';

import { listDevicesAsync } from '../commands/listDevicesAsync';
import { Device } from '../utils/device';

export const useListDevices = () => {
const [devices, setDevices] = useState<Device[]>([]);
Expand Down
12 changes: 9 additions & 3 deletions apps/menu-bar/src/popover/Core.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Device } from 'common-types/devices';
import React, { memo, useCallback, useEffect, useState } from 'react';
import { Alert, SectionList } from 'react-native';

Expand Down Expand Up @@ -28,7 +29,12 @@ import {
saveSelectedDevicesIds,
} from '../modules/Storage';
import { openProjectsSelectorURL } from '../utils/constants';
import { Device, getDeviceId, getDeviceOS, getSectionsFromDeviceList } from '../utils/device';
import {
getDeviceId,
getDeviceOS,
getSectionsFromDeviceList,
isVirtualDevice,
} from '../utils/device';
import { getPlatformFromURI } from '../utils/parseUrl';
import { useExpoTheme } from '../utils/useExpoTheme';

Expand Down Expand Up @@ -86,15 +92,15 @@ function Core(props: Props) {
return (
devices.find((d) => getDeviceId(d) === selectedDevicesIds.ios) ??
devices.find((d) => getDeviceId(d) === selectedDevicesIds.android) ??
devices?.find((d) => d.state === 'Booted')
devices?.find((d) => isVirtualDevice(d) && d.state === 'Booted')
);
},
[devices, selectedDevicesIds]
);

const ensureDeviceIsRunning = useCallback(
async (device: Device) => {
if (device.state !== 'Shutdown') {
if (!isVirtualDevice(device) || device.state === 'Booted') {
return;
}

Expand Down
19 changes: 5 additions & 14 deletions apps/menu-bar/src/utils/device.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Device, IosSimulator, AndroidEmulator } from 'common-types/devices';
import { SectionListData } from 'react-native';

export type BaseDevice = {
Expand All @@ -15,20 +16,6 @@ export type BaseDevice = {
}
);

export type IOSDevice = BaseDevice & {
osType: 'iOS';
udid: string;
deviceType: 'simulator' | 'device';
};

export type AndroidDevice = BaseDevice & {
osType: 'android';
pid?: number;
deviceType: 'emulator' | 'device';
};

export type Device = AndroidDevice | IOSDevice;

export function getDeviceOS(device: Device): 'android' | 'ios' {
return device.osType.toLowerCase() as 'android' | 'ios';
}
Expand Down Expand Up @@ -68,3 +55,7 @@ export function getSectionsFromDeviceList(

return sections;
}

export function isVirtualDevice(device: Device): device is IosSimulator | AndroidEmulator {
return device.deviceType === 'simulator' || device.deviceType === 'emulator';
}
8 changes: 7 additions & 1 deletion apps/menu-bar/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"extends": "@tsconfig/react-native/tsconfig.json"
"extends": "@tsconfig/react-native/tsconfig.json",
"compilerOptions": {
"paths": {
"common-types/*": ["../../common-types/src/*"]
}
},
"references": [{ "path": "../../common-types/tsconfig.json" }]
}
51 changes: 51 additions & 0 deletions common-types/src/devices.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export interface AppleConnectedDevice {
/** @example `00008101-001964A22629003A` */
udid: string;
/** @example `Evan's phone` */
name: string;
/** @example `iPhone13,4` */
model: string;
/** @example `device` */
deviceType: "device" | "catalyst";
/** @example `USB` */
connectionType: "USB" | "Network";
/** @example `15.4.1` */
osVersion: string;
osType: "iOS";
}

export interface IosSimulator {
runtime: string;
osVersion: string;
windowName: string;
osType: "iOS";
state: "Booted" | "Shutdown";
isAvailable: boolean;
name: string;
udid: string;
lastBootedAt?: number;
deviceType: "simulator";
}

export interface AndroidEmulator {
pid?: string;
name: string;
osType: "Android";
deviceType: "emulator";
state: "Booted" | "Shutdown";
}

export interface AndroidConnectedDevice {
pid?: string;
model: string;
name: string;
osType: "Android";
deviceType: "device";
connectionType?: "USB" | "Network";
}

export type Device =
| AppleConnectedDevice
| IosSimulator
| AndroidEmulator
| AndroidConnectedDevice;
8 changes: 8 additions & 0 deletions common-types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.base",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}
3 changes: 1 addition & 2 deletions packages/eas-shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { runAppOnIosSimulatorAsync, runAppOnAndroidEmulatorAsync } from "./run";
import * as Emulator from "./run/android/emulator";
import { assertExecutablesExistAsync as validateAndroidSystemRequirementsAsync } from "./run/android/systemRequirements";
import AppleDevice, { AppleConnectedDevice } from "./run/ios/device";
import AppleDevice from "./run/ios/device";
import * as Simulator from "./run/ios/simulator";
import { validateSystemRequirementsAsync as validateIOSSystemRequirementsAsync } from "./run/ios/systemRequirements";

Expand All @@ -21,5 +21,4 @@ export {
Emulator,
Simulator,
AppleDevice,
AppleConnectedDevice,
};
Loading