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] Improve Platform filtering UI #84

Merged
merged 2 commits into from
Oct 19, 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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### 🎉 New features

- Add ability to show/hide different types of simulators, and add experimental TV support. ([#77](https://github.com/expo/orbit/pull/77) by [@douglowder](https://github.com/douglowder))
- Add ability to show/hide different types of simulators, and add experimental TV support. ([#77](https://github.com/expo/orbit/pull/77) by [@douglowder](https://github.com/douglowder), [#84](https://github.com/expo/orbit/pull/84) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Add support for opening tarballs with multiple apps. ([#73](https://github.com/expo/orbit/pull/73) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Improve feedback to the user when an error occurs. ([#64](https://github.com/expo/orbit/pull/64) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Added drag and drop support for installing apps. ([#57](https://github.com/expo/orbit/pull/57) by [@gabrieldonadel](https://github.com/gabrieldonadel))
Expand Down
19 changes: 13 additions & 6 deletions apps/menu-bar/src/components/PathInput.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { darkTheme, lightTheme } from '@expo/styleguide-native';
import React from 'react';
import { StyleSheet, TouchableOpacity, TextInput as NativeTextInput } from 'react-native';

import { TextInput } from './Text';
import { Row } from './View';
import FolderIcon from '../assets/icons/folder.svg';
import FilePicker from '../modules/FilePickerModule';
import { useExpoTheme } from '../utils/useExpoTheme';
import { addOpacity } from '../utils/theme';
import { useCurrentTheme, useExpoTheme } from '../utils/useExpoTheme';

const PathInput = React.forwardRef<NativeTextInput, React.ComponentProps<typeof TextInput>>(
({ onChangeText, editable, ...props }, forwardedRef) => {
const theme = useExpoTheme();
const theme = useCurrentTheme();
const expoTheme = useExpoTheme();

const handleSelectFolder = async () => {
try {
Expand All @@ -18,13 +21,17 @@ const PathInput = React.forwardRef<NativeTextInput, React.ComponentProps<typeof
} catch {}
};

const backgroundColor =
theme === 'light'
? addOpacity(lightTheme.background.default, 0.6)
: addOpacity(darkTheme.background.default, 0.2);

return (
<Row
border="default"
border="light"
rounded="medium"
bg={editable ? 'overlay' : 'secondary'}
align="center"
style={[styles.inputContainer, !editable && styles.inputDisabled]}>
style={[styles.inputContainer, { backgroundColor }, !editable && styles.inputDisabled]}>
<TextInput
shadow="input"
{...props}
Expand All @@ -36,7 +43,7 @@ const PathInput = React.forwardRef<NativeTextInput, React.ComponentProps<typeof
placeholder="Android SDK root path"
/>
<TouchableOpacity style={styles.icon} onPress={handleSelectFolder} disabled={!editable}>
<FolderIcon fill={theme.text.default} height={18} width={18} />
<FolderIcon fill={expoTheme.text.default} height={18} width={18} />
</TouchableOpacity>
</Row>
);
Expand Down
4 changes: 3 additions & 1 deletion apps/menu-bar/src/components/View.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
borderDark,
border,
gap,
addOpacity,
} from '../utils/theme';

export const View = create(RNView, {
Expand Down Expand Up @@ -84,6 +85,7 @@ export const View = create(RNView, {

border: {
default: { borderColor: lightTheme.border.default, borderWidth: 1 },
light: { borderColor: addOpacity(lightTheme.border.default, 0.2), borderWidth: 1 },
hairline: {
borderColor: lightTheme.border.default,
borderWidth: StyleSheet.hairlineWidth,
Expand Down Expand Up @@ -239,7 +241,7 @@ export const Divider = create(RNView, {
base: {
height: 1,
backgroundColor: palette.light.gray['700'],
opacity: 0.4,
opacity: 0.1,
},

variants: {
Expand Down
6 changes: 4 additions & 2 deletions apps/menu-bar/src/hooks/useListDevices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { useCallback, useEffect, useState } from 'react';
import { DeviceEventEmitter } from 'react-native';

import { listDevicesAsync } from '../commands/listDevicesAsync';
import { UserPreferences } from '../modules/Storage';
import { getUserPreferences } from '../modules/Storage';
import { getSectionsFromDeviceList } from '../utils/device';

export const useListDevices = (userPreferences: UserPreferences) => {
export const useListDevices = () => {
const userPreferences = getUserPreferences();

const [devicesPerPlatform, setDevicesPerPlatform] = useState<DevicesPerPlatform>({
android: { devices: [] },
ios: { devices: [] },
Expand Down
60 changes: 2 additions & 58 deletions apps/menu-bar/src/popover/Core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { bootDeviceAsync } from '../commands/bootDeviceAsync';
import { downloadBuildAsync } from '../commands/downloadBuildAsync';
import { installAndLaunchAppAsync } from '../commands/installAndLaunchAppAsync';
import { launchSnackAsync } from '../commands/launchSnackAsync';
import { Checkbox, Spacer, Text, View } from '../components';
import { Spacer, Text, View } from '../components';
import DeviceItem, { DEVICE_ITEM_HEIGHT } from '../components/DeviceItem';
import ProgressIndicator from '../components/ProgressIndicator';
import { useDeepLinking } from '../hooks/useDeepLinking';
Expand All @@ -32,9 +32,6 @@ import {
SelectedDevicesIds,
getSelectedDevicesIds,
saveSelectedDevicesIds,
UserPreferences,
getUserPreferences,
saveUserPreferences,
} from '../modules/Storage';
import { openProjectsSelectorURL } from '../utils/constants';
import { getDeviceId, getDeviceOS, isVirtualDevice } from '../utils/device';
Expand All @@ -48,7 +45,6 @@ enum Status {
}

const BUILDS_SECTION_HEIGHT = 88;
const DEVICES_TO_SHOW_SECTION_HEIGHT = 22;

type Props = {
isDevWindow: boolean;
Expand All @@ -58,7 +54,6 @@ function Core(props: Props) {
const [selectedDevicesIds, setSelectedDevicesIds] = useState<SelectedDevicesIds>(
getSelectedDevicesIds()
);
const [userPreferences, setUserPreferences] = useState<UserPreferences>(getUserPreferences());

const { apps, refetch: refetchApps } = useGetPinnedApps();
usePopoverFocusEffect(refetchApps);
Expand All @@ -68,8 +63,7 @@ function Core(props: Props) {
const [status, setStatus] = useState(Status.LISTENING);
const [progress, setProgress] = useState(0);

const { devicesPerPlatform, numberOfDevices, sections, refetch } =
useListDevices(userPreferences);
const { devicesPerPlatform, numberOfDevices, sections, refetch } = useListDevices();
const { emulatorWithoutAudio } = useDeviceAudioPreferences();
const theme = useExpoTheme();

Expand All @@ -79,7 +73,6 @@ function Core(props: Props) {
(displayDimensions.height || 0) -
FOOTER_HEIGHT -
BUILDS_SECTION_HEIGHT -
DEVICES_TO_SHOW_SECTION_HEIGHT -
(showProjectsSection ? PROJECTS_SECTION_HEIGHT : 0) -
30;
const heightOfAllDevices =
Expand Down Expand Up @@ -118,33 +111,6 @@ function Core(props: Props) {
[emulatorWithoutAudio]
);

const onPressShowIosSimulators = async (value: boolean) => {
const newPreferences = {
...userPreferences,
showIosSimulators: value,
};
saveUserPreferences(newPreferences);
setUserPreferences(newPreferences);
};

const onPressShowTvosSimulators = async (value: boolean) => {
const newPreferences = {
...userPreferences,
showTvosSimulators: value,
};
saveUserPreferences(newPreferences);
setUserPreferences(newPreferences);
};

const onPressShowAndroidEmulators = async (value: boolean) => {
const newPreferences = {
...userPreferences,
showAndroidEmulators: value,
};
saveUserPreferences(newPreferences);
setUserPreferences(newPreferences);
};

// @TODO: create another hook
const handleSnackUrl = useCallback(
async (url: string) => {
Expand Down Expand Up @@ -310,28 +276,6 @@ function Core(props: Props) {
) : null}
</View>
{apps?.length ? <ProjectsSection apps={apps} /> : null}
<View px="medium" style={{ flexDirection: 'row', height: DEVICES_TO_SHOW_SECTION_HEIGHT }}>
<Text size="small" weight="normal">
Devices to show:
</Text>
<Checkbox
value={userPreferences.showIosSimulators}
onValueChange={onPressShowIosSimulators}
label="iOS"
/>
{userPreferences.showExperimentalFeatures ? (
<Checkbox
value={userPreferences.showTvosSimulators}
onValueChange={onPressShowTvosSimulators}
label="tvOS"
/>
) : null}
<Checkbox
value={userPreferences.showAndroidEmulators}
onValueChange={onPressShowAndroidEmulators}
label="Android"
/>
</View>
<View shrink="1" pt="tiny">
<SectionList
sections={sections}
Expand Down
1 change: 1 addition & 0 deletions apps/menu-bar/src/utils/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export const border = {
borderColor: PlatformColor('gridColor'),
borderWidth: 1,
},
light: { borderColor: addOpacity(lightTheme.border.default, 0.2), borderWidth: 1 },
warning: { borderColor: lightTheme.border.warning, borderWidth: 1 },
hairline: {
borderColor: lightTheme.border.default,
Expand Down
111 changes: 86 additions & 25 deletions apps/menu-bar/src/windows/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react';
import { Alert, StyleSheet, TouchableOpacity } from 'react-native';
import { darkTheme, lightTheme } from '@expo/styleguide-native';
import React, { Fragment, useEffect, useState } from 'react';
import { Alert, StyleSheet, TouchableOpacity, Switch } from 'react-native';

import { WindowsNavigator } from './index';
import { withApolloProvider } from '../api/ApolloClient';
Expand All @@ -22,8 +23,15 @@ import WebAuthenticationSessionModule, {
WebBrowserResultType,
} from '../modules/WebAuthenticationSessionModule';
import { getCurrentUserDisplayName } from '../utils/helpers';
import { addOpacity } from '../utils/theme';
import { useCurrentTheme } from '../utils/useExpoTheme';

const osList: { label: string; key: keyof UserPreferences; experimental?: boolean }[] = [
{ label: 'Android', key: 'showAndroidEmulators' },
{ label: 'iOS', key: 'showIosSimulators' },
{ label: 'tvOS', key: 'showTvosSimulators', experimental: true },
];

const Settings = () => {
const theme = useCurrentTheme();
const [hasSessionSecret, setHasSessionSecret] = useState(
Expand Down Expand Up @@ -129,6 +137,15 @@ const Settings = () => {
setHasSessionSecret(false);
};

const toggleOS = async (key: keyof UserPreferences, value: boolean) => {
const newPreferences = {
...userPreferences,
[key]: value,
};
saveUserPreferences(newPreferences);
setUserPreferences(newPreferences);
};

return (
<View flex="1" px="medium" pb="medium">
<View flex="1">
Expand Down Expand Up @@ -186,15 +203,14 @@ const Settings = () => {
<Text size="medium" weight="semibold">
Preferences
</Text>
<Row mb="3.5" align="center" justify="between">
<Row mb="2" align="center" justify="between">
<Checkbox
value={automaticallyChecksForUpdates}
onValueChange={onPressSetAutomaticallyChecksForUpdates}
label="Check for updates automatically"
/>
<Button
color="primary"
style={{}}
title="Check for updates"
onPress={SparkleModule.checkForUpdates}
/>
Expand All @@ -217,30 +233,71 @@ const Settings = () => {
<Checkbox
value={userPreferences.showExperimentalFeatures}
onValueChange={onPressSetShowExperimentalFeatures}
label="Show experimental features (requires restart)"
label="Show experimental features"
/>
</Row>
<Row mb="2" align="center">
<Checkbox
value={customSdkPathEnabled}
onValueChange={toggleCustomSdkPath}
label="Custom Android SDK root location"
/>
</Row>
<PathInput
editable={customSdkPathEnabled}
onChangeText={(text) => {
setUserPreferences((prev) => {
const newPreferences = { ...prev, customSdkPath: text };
saveUserPreferences(newPreferences);
MenuBarModule.setEnvVars({
ANDROID_HOME: text,
<View mb="3.5">
<Row mb="2" align="center">
<Checkbox
value={customSdkPathEnabled}
onValueChange={toggleCustomSdkPath}
label="Custom Android SDK root location"
/>
</Row>
<PathInput
editable={customSdkPathEnabled}
onChangeText={(text) => {
setUserPreferences((prev) => {
const newPreferences = { ...prev, customSdkPath: text };
saveUserPreferences(newPreferences);
MenuBarModule.setEnvVars({
ANDROID_HOME: text,
});
return newPreferences;
});
return newPreferences;
});
}}
value={userPreferences.customSdkPath}
/>
}}
value={userPreferences.customSdkPath}
/>
</View>
<View>
<Text size="medium" weight="medium">
Platforms
</Text>
<Text size="tiny" color="secondary">
Only devices for the enabled platforms will be listed in the menu bar
</Text>
<View
mt="1.5"
rounded="medium"
style={{
backgroundColor:
theme === 'light'
? addOpacity(lightTheme.background.default, 0.6)
: addOpacity(darkTheme.background.default, 0.2),
}}
border="light"
px="2">
{osList
.filter(
({ experimental }) => !experimental || userPreferences.showExperimentalFeatures
)
.map(({ label, key }, index, list) => (
<Fragment key={key}>
<Row align="center" justify="between">
<Text size="small" weight="normal">
{label}
</Text>
<Switch
value={Boolean(userPreferences[key])}
onValueChange={(value) => toggleOS(key, value)}
style={styles.switch}
/>
</Row>
{list.length - 1 !== index ? <Divider /> : null}
</Fragment>
))}
</View>
</View>
</View>
<Divider mb="tiny" />
<View py="tiny">
Expand Down Expand Up @@ -275,4 +332,8 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
},
switch: {
width: 40,
height: 40,
},
});
2 changes: 1 addition & 1 deletion apps/menu-bar/src/windows/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const WindowsNavigator = createWindowsNavigator({
// eslint-disable-next-line no-bitwise
mask: WindowStyleMask.Titled | WindowStyleMask.Closable,
titlebarAppearsTransparent: true,
height: 400,
height: 580,
width: 500,
},
},
Expand Down