Skip to content

Commit

Permalink
[menu-bar] Improve Platform filtering UI (#84)
Browse files Browse the repository at this point in the history
* [menu-bar] Improve OS filter settings

* Add changelog entry
  • Loading branch information
gabrieldonadel authored Oct 19, 2023
1 parent 4d30579 commit e21a44b
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 94 deletions.
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

0 comments on commit e21a44b

Please sign in to comment.